Java虚拟机调用jni_JNI攻略之十一――启动虚拟机调用java类
JNI攻略之十一――啟動(dòng)虛擬機(jī)調(diào)用java類
江蘇無錫繆小東
一、一個(gè)簡(jiǎn)單的java程序
下面是一個(gè)簡(jiǎn)單的java程序!主要是供虛擬機(jī)直接調(diào)用的!我們可以編寫任意的java程序,然后在c中調(diào)用虛擬機(jī)執(zhí)行它!通常我們會(huì)有此場(chǎng)景:某些本地系統(tǒng)可能不支持多線程,但你對(duì)java的多線程又比較精通,同時(shí)對(duì)c還是比較了解,此時(shí)我們就可以在c中調(diào)用虛擬機(jī),執(zhí)行改線程程序!更一般的:以前有一個(gè)用c寫的服務(wù)器程序,它可以介紹客戶的申請(qǐng),當(dāng)然這種申請(qǐng)?jiān)谀骋粋€(gè)時(shí)刻肯定是很多很多的,因此我們就想讓這些申請(qǐng)交由java的線程完成!此時(shí)就可以使用c調(diào)用虛擬機(jī)執(zhí)行線程操作!對(duì)用戶隱藏了內(nèi)部調(diào)用虛擬機(jī)執(zhí)行線程的細(xì)節(jié)!
//示例程序Prog.java
public class Prog {
public static void main(String[] args) {
System.out.println("Hello World " + args[0]);
}
}
二、調(diào)用虛擬機(jī)執(zhí)行java程序的代碼
下面是啟動(dòng)虛擬機(jī)執(zhí)行java程序的過程。(在此之前請(qǐng)先閱讀上面一篇)
/* invoke&exec.c */
#include
#include
int main() {
int res;
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[3];//以上是啟動(dòng)虛擬機(jī)的一些參數(shù)
jclass cls , strcls;//將要被虛擬機(jī)執(zhí)行的類和創(chuàng)建的String類
jmethodID mid ;//類的方法標(biāo)識(shí)符
jstring jstr ;//輸入?yún)?shù)
jobjectArray args ;//主函數(shù)輸入?yún)?shù)
vm_args.version=JNI_VERSION_1_2;//這個(gè)字段必須設(shè)置為該值
/*設(shè)置初始化參數(shù)*/
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.class.path=.";
options[2].optionString = "-verbose:jni";//用于跟蹤運(yùn)行時(shí)的信息
/*版本號(hào)設(shè)置不能漏*/
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 3;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (res < 0) {
fprintf(stderr, "Can't create Java VMn");
//exit(1);
}
//建立一個(gè)類及其方法,調(diào)用其方法的過程。和前面操作java的方法完全一樣哦!
cls = (*env)->FindClass(env, "Prog");
if (cls == NULL) {goto destroy;}
mid = (*env)->GetStaticMethodID(env, cls, "main","([Ljava/lang/String;)V");
if (mid == NULL) {goto destroy;}
jstr = (*env)->NewStringUTF(env, " This Method is called from C!");
if (jstr == NULL) {goto destroy;}
strcls = (*env)->FindClass(env, "java/lang/String");
args = (*env)->NewObjectArray(env, 1, strcls, jstr);
if (args == NULL) {goto destroy;}
(*env)->CallStaticVoidMethod(env, cls, mid, args);
destroy:
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
(*jvm)->DestroyJavaVM(jvm);
fprintf(stdout, "Java VM destory.n");
}
三、執(zhí)行結(jié)果
以下是執(zhí)行結(jié)果的主要部分!
[Dynamic-linking native method java.lang.Float.intBitsToFloat ... JNI]
[Dynamic-linking native method java.lang.Double.longBitsToDouble ... JNI]
[Dynamic-linking native method java.lang.Float.floatToIntBits ... JNI]
[Dynamic-linking native method java.lang.Double.doubleToLongBits ... JNI]
[Dynamic-linking native method java.lang.Object.registerNatives ... JNI]
[Registering JNI native method java.lang.Object.hashCode]
[Registering JNI native method java.lang.Object.wait]
……
[Registering JNI native method sun.misc.Unsafe.getShortVolatile]
[Registering JNI native method sun.misc.Unsafe.staticFieldOffset]
……
[Dynamic-linking native method java.io.FileOutputStream.writeBytes ... JNI]
Hello WorldThis Method is called from C!
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Java VM destory.
后面3個(gè)分別是C中的輸出、main方法的輸入――調(diào)用aaa XXXX > 11.txt和c中最后的輸出!
執(zhí)行此exe程序,必須將Prog.class放到同一個(gè)目錄中!
總結(jié)
以上是生活随笔為你收集整理的Java虚拟机调用jni_JNI攻略之十一――启动虚拟机调用java类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java程序死了telnet还有用吗_j
- 下一篇: linux去掉java路径_Java显示