开发环境:

操作系统: (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 文件 :

 #include <jni.h>
#include <iostream>
#include <string.h>
using std::cout;
using std::endl;
using std::hex;
int main ()
{
/* where everything is defined */ JavaVM *jvm = NULL; /* denotes a Java VM */
JNIEnv *env = NULL; /* pointer to native method interface the JNI interface pointer 只在当前thread中有效*/
JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
JavaVMOption* options = new JavaVMOption[];
options[].optionString = const_cast<char *>("-Djava.class.path=.");///usr/lib/jvm/java-7-openjdk-amd64/jre/lib /usr/lib/java vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = ;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE; /* load and initialize a Java VM, return a JNI interface
* pointer in env */
bool flag = false;
if (JNI_CreateJavaVM(&jvm,(void **) &env, &vm_args)!=JNI_OK)
{ cout << "JNI not JNI_OK" << endl; flag = true; }
if (jvm==NULL)
{ cout << "jvm is null!" << endl; flag = true; }
if (env==NULL)
{ cout << "env is null!" << endl; flag = true; }
if (flag) { cout.flush(); return -;} delete options;
/* invoke the Main.test method using the JNI */
jclass cls = env->FindClass("Main");
jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
env->CallStaticVoidMethod(cls, mid, );
/* We are done. */
jvm->DestroyJavaVM();
cout << "end of create vm \n";
return ;
}

运行脚本 :

#!/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--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
end of create vm

问题总结 & 注意事项:

  1. 指定JNI的头文件正确路径
  2. 指定libjvm.so的正确路径, g++编译选项最后加上-ljvm (否则编译不通过)
  3. c++ 代码中第15行设置java.class.path时要指向你使用的类的目录  (会导致创建VM失败,aborted (cord dumped)
  4. -fpermissive 参数可以去掉,刚开始没有对JNI_CreateJavaVM的第二个参数强制类型转换,参数error

参考教程:

Oracle 官方指南  http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/invocation.html#wp9502

相关问题:

创建VM 失败  aborted , stackoverflow上的一个问题

04-02 23:47