C語言呼叫 Java(Linux)

工程師WWW發表於2015-09-02

一、書寫C檔案,模擬JDK中自帶的java命令

  1. #include <jni.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. int main(int argc, char*argv[]) 
  5. {  
  6.   
  7.   JavaVM *jvm;  
  8.    JNIEnv *env;  
  9.      JavaVMInitArgs vm_args;  
  10.      JavaVMOption options[1];  
  11.   
  12.      jobjectArray applicationArgs;  
  13.      jstring appArg;  
  14.   
  15.      /* 
  16.       * Setting VM arguments 
  17.       */  
  18.      vm_args.version = JNI_VERSION_1_2;  
  19.      vm_args.ignoreUnrecognized = JNI_TRUE;  
  20.      vm_args.nOptions = 0;  
  21.   
  22.      /* 
  23.       * Setting classpath 
  24.       */  
  25.      char classpath[1024] = "-Djava.class.path=";  
  26.      char *env_classpath = getenv("CLASSPATH");  
  27.   
  28.      int mainclass_index = 1;  
  29.      if (argc >= 3 && !strcmp("-classpath", argv[1])) {  
  30.          options[0].optionString = strcat(classpath, argv[2]);  
  31.          vm_args.nOptions++;  
  32.          mainclass_index += 2;  
  33.      } else if (env_classpath) {  
  34.          options[0].optionString = strcat(classpath, env_classpath);  
  35.          vm_args.nOptions++;  
  36.      }  
  37.   
  38.      if (vm_args.nOptions > 0) {  
  39.          vm_args.options = options;  
  40.      }  
  41.   
  42.      if (mainclass_index >= argc) {  
  43.          printf("Main class not found, please specify it\n");  
  44.          return 0;  
  45.      }  
  46.   
  47.      jint res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);  
  48.      if (res < 0) {  
  49.          printf("Create Java VM error, code = %d\n", res);  
  50.          return -1;  
  51.      }  
  52.   
  53.      jclass cls = (*env)->FindClass(env, argv[mainclass_index]);  
  54.      if (!cls) {  
  55.          printf("Class %s not found\n", argv[mainclass_index]);  
  56.          return -1;  
  57.      }  
  58.   
  59.      jmethodID mid = (*env)->GetStaticMethodID(env, cls, "main""([Ljava/lang/String;)V");  
  60.   
  61.      if (!mid) {  
  62.          printf("Method %s of Class %s not found\n""main", argv[mainclass_index]);  
  63.          return -1;  
  64.      }  
  65.      applicationArgs = (*env)->NewObjectArray(env, argc - mainclass_index - 1,  
  66.                                               (*env)->FindClass(env, "java/lang/String"),  
  67.                                               NULL);  
  68.   
  69.      int i = 0;  
  70.      for (i = mainclass_index + 1; i < argc; i ++) {  
  71.          appArg = (*env)->NewStringUTF(env, argv[i]);  
  72.          (*env)->SetObjectArrayElement(env, applicationArgs, i - mainclass_index - 1, appArg);  
  73.      }  
  74.   
  75.      (*env)->CallStaticVoidMethod(env, cls, mid, applicationArgs);  

  76.      printf("before destroy\n");  
  77.      /* 
  78.       * Destroy the JVM. 
  79.       * This is necessary, otherwise if the called method exits, 
  80.       * this program will return immediately. 
  81.       */  
  82.      (*jvm)->DestroyJavaVM(jvm);  
  83.      printf("after destroy\n");  
  84.   
  85.      return 0;  
  86.  }  

二、編譯,書寫makefile檔案 ,注意要連結JDK中所自帶的jvm.so檔案,“-L/usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/bin/classic” 

  1. all:CCallJava  
  2. CCallJava:  
  3.     gcc -o CCallJava CCallJava.c -I/usr/lib64/jvm/java-1_6_0-ibm-1.6.0/include/ -I/usr/lib64/jvm/java-1_6_0-ibm-1.6.0/include/linux/ -L/usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/bin/classic -ljvm  -ldl

三、修改.bash_profile檔案,設定環境變數,即libjvm.so 所在的路徑

export LD_LIBRARY_PATH=/usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/bin/classic

四、執行命令./CCallJava -classpath . Test 34 67

結果如下

 

至此,C語言呼叫Java程式完成

 

參考資料:

http://supermmx.org/blog/20060811_calling_java_from_c_cplusplus

相關文章