C語言呼叫java
阿新 • • 發佈:2019-07-01
C語言呼叫java也是通過JNI實現的,Linux平臺也就是引入libjvm.so動態連結庫就可以。首先需要編寫java類
public class Sample {
public static void test2() {
System.out.println("java列印的helloword");
}
}
這是非常簡單的一個java類,裡面就只有一個java方法。等下我們就要通過C來呼叫這個方法。jvm只認識class,首先得編譯它,java Sample.java。在當前目錄得到一個Sample.class的檔案。這個檔案等下會被我們的C程式載入。
然後編寫C程式碼。
#include <jni.h>//引入jni的標頭檔案,下面載入類和呼叫類的方法都是通過jni裡面的函式實現的 #include <string.h> int main() { JavaVMOption options[1]; JNIEnv *env; JavaVM *jvm; JavaVMInitArgs vm_args; long status; jclass cls; jmethodID mid; jint square; jboolean not; options[0].optionString = "-Djava.class.path=."; //設定classpath memset(&vm_args, 0, sizeof(vm_args)); vm_args.version = JNI_VERSION_1_2; vm_args.nOptions = 1; vm_args.options = options; status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); if (status != JNI_ERR) { //cls = (*env)->FindClass(env, "java/lang/Object"); cls=(*env)->FindClass(env,"Sample");//通過FindClass函式找到這個類,這裡需要新增類的描述符合,如果是Object就應該是java/lang/Object printf("find the class\n"); if(cls !=0) { //mid = (*env)->GetStaticMethodID(env, cls, "main", "(I)I"); mid=(*env)->GetStaticMethodID(env,cls,"main","([Ljava/lang/String;)V");//通過函式找到方法,這裡面應該是方法的描述符。 printf("find the method\n"); if(mid !=0) { printf("exec method\n"); square = (*env)->CallStaticIntMethod(env, cls, mid, NULL); //執行方法 printf("Result of intMethod: %d\n", square); } mid = (*env)->GetStaticMethodID(env, cls, "booleanMethod", "(Z)Z"); if(mid !=0) { not = (*env)->CallStaticBooleanMethod(env, cls, mid, 1); printf("Result of booleanMethod: %d\n", not); } } else{ printf("not found\n"); } (*jvm)->DestroyJavaVM(jvm); return 0; } else return -1; }
,如果直接gcc 是會報錯的,因為jni標頭檔案不在系統的標頭檔案裡面。而且動態連結庫也不在系統預設的庫裡面。所以編寫一個Makefile:
compile:
gcc calljvm.c -I $JAVA_HOME/include/ -I $JAVA_HOME/include/linux/ -L$JAVA_HOME/jre/lib/amd64/server/ -ljvm -o calljvm
執行make,順利應該編譯通過,但是執行是會報錯的。因為libjvm.so不在/usr/lib 裡面。所以得把jvm的庫加到系統庫路徑裡面
export LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/amd64/:$JAVA_HOME/jre/lib/amd64/servr
系統預設會在/usr/lib裡面尋找動態連結庫,如果有LD_LIBRARY_PATH之後會優先在LD_LIBRARY_PATH指定路徑找,如果找不到再去/usr/lib。
再次編譯連結執