zoukankan      html  css  js  c++  java
  • 入门: 使用JNI 从C++代码中调用Java的静态方法

    开发环境:

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

    问题总结 & 注意事项:

    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上的一个问题 

  • 相关阅读:
    $Poj2228$/洛谷$SP283 Naptime$ 环形$DP$
    $Poj1952 $洛谷$1687 Buy Low,Buy Lower$ 线性$DP+$方案计数
    $Poj3585 Accumulation Degree$ 树形$DP/$二次扫描与换根法
    洛谷$1541$ 乌龟棋 线性$DP$
    $Loj10157$ 皇宫看守 树形$DP$
    $loj10156/$洛谷$2016$ 战略游戏 树形$DP$
    $Loj10155$ 数字转换(求树的最长链) 树形$DP$
    洛谷$2015$二叉苹果树
    $CH5302$ 金字塔 区间$DP$/计数类$DP$
    [hiho1035] 自驾旅行III
  • 原文地址:https://www.cnblogs.com/ridox/p/3702667.html
Copyright © 2011-2022 走看看