开发环境:
操作系统: (uname -a output) Linux ubuntu 3.8.0-19-generic #29-Ubuntu SMP Wed Apr 17 18:16:28 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
JDK 版本 : (java -version)
java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-0ubuntu0.13.04.2)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
G++ 版本: (g++ --version) g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3
首先 Main.java 文件 :
public class Main { public static void test(int time ) { System.out.println("time is " + 2*time); } }
创建 api.cpp 文件 :
1 #include <jni.h> 2 #include <iostream> 3 #include <string.h> 4 using std::cout; 5 using std::endl; 6 using std::hex; 7 int main () 8 { 9 /* where everything is defined */ 10 11 JavaVM *jvm = NULL; /* denotes a Java VM */ 12 JNIEnv *env = NULL; /* pointer to native method interface the JNI interface pointer 只在当前thread中有效*/ 13 JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */ 14 JavaVMOption* options = new JavaVMOption[1]; 15 options[0].optionString = const_cast<char *>("-Djava.class.path=.");///usr/lib/jvm/java-7-openjdk-amd64/jre/lib /usr/lib/java 16 17 vm_args.version = JNI_VERSION_1_6; 18 vm_args.nOptions = 1; 19 vm_args.options = options; 20 vm_args.ignoreUnrecognized = JNI_TRUE; 21 22 /* load and initialize a Java VM, return a JNI interface 23 * pointer in env */ 24 bool flag = false; 25 if (JNI_CreateJavaVM(&jvm,(void **) &env, &vm_args)!=JNI_OK) 26 { cout << "JNI not JNI_OK" << endl; flag = true; } 27 if (jvm==NULL) 28 { cout << "jvm is null!" << endl; flag = true; } 29 if (env==NULL) 30 { cout << "env is null!" << endl; flag = true; } 31 if (flag) { cout.flush(); return -1;} 32 33 34 delete options; 35 /* invoke the Main.test method using the JNI */ 36 jclass cls = env->FindClass("Main"); 37 jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V"); 38 env->CallStaticVoidMethod(cls, mid, 100); 39 /* We are done. */ 40 jvm->DestroyJavaVM(); 41 cout << "end of create vm "; 42 return 0; 43 }
运行脚本 :
#!/bin/sh JNI_INCLUDE="-I/usr/lib/jvm/java-7-openjdk-amd64/include -I/usr/lib/jvm/java-7-openjdk-amd64/include/linux " JNILIB="-L/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server" JAVASOURCE=`find . -name "*.java"` CPPSOURCE=`find . -name "*.cpp"` export LD_LIBRARY_PATH=/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server:. echo "============================================" javac $JAVASOURCE echo 'Java files compiled' g++ -Wall $JNI_INCLUDE $JNILIB -L/usr/bin/java -fPIC -fpermissive $CPPSOURCE -o $test.out -ljvm
./test.out
输出脚本的结果:
Java files compiled time is 200 end of create vm
问题总结 & 注意事项:
- 指定JNI的头文件正确路径
- 指定libjvm.so的正确路径, g++编译选项最后加上-ljvm (否则编译不通过)
- c++ 代码中第15行设置java.class.path时要指向你使用的类的目录 (会导致创建VM失败,aborted (cord dumped)
- -fpermissive 参数可以去掉,刚开始没有对JNI_CreateJavaVM的第二个参数强制类型转换,参数error
参考教程:
Oracle 官方指南 http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/invocation.html#wp9502
相关问题:
创建VM 失败 aborted , stackoverflow上的一个问题