`

Linux下JNI调用

阅读更多

 做 项目,无论是遗留产品的再生产,还是对遗留产品的再利用,都不可避免的会出现一大堆的异构现象。解决异构通信问题是这类项目的主要问题。以前看见这种情况 第一个解决方案就是Socket通信。说实在的自己实现Socket通信,定制通信协议,或者是实现已有的通信协议都是很头痛的事情。本人有不堪回首的历 史经历。

    最近同样在项目中需要去解决一个异构问题,由于时间的紧迫,以及先天的运行环境(两个部分是运行在同一台机器上的)。考虑到了使用JNI,结果表明JNI 是完全可以胜任目前的角色的。以前没有了解过JNI,总是以为它这不好那不好,用了用,表现还不错,而且实现起来非常之简单。

    整个实现过程可以分为五步来完成:

1)写一个声明了native的Java文件:

package example;

public   class  TestJNI 
{
    
static  
{
        System.loadLibrary(
" test "
);
    }

    
    
public  native String getNameCPP();
}


2)  使用javah产生对应的CPP头文件:
命令:javah -classpath <path> -jni example.TestJNI -d <out_dir>
生成的头文件example_TestJNI.h如下:
/*  DO NOT EDIT THIS FILE - it is machine generated  */
#include 
< jni.h >
/*  Header for class example_TestJNI  */

#ifndef _Included_example_TestJNI
#define  _Included_example_TestJNI
#ifdef __cplusplus
extern   " C "   {
#endif
/*
 * Class:     example_TestJNI
 * Method:    getNameForCPP
 * Signature: ()Ljava/lang/String;
 
*/
JNIEXPORT jstring JNICALL Java_example_TestJNI_getNameForCPP
  (JNIEnv 
* , jobject);

#ifdef __cplusplus
}

#endif
#endif

3)实现对应的CPP代码:
#include  " example_TestJNI.h "
#include 
< string >

JNIEXPORT jstring JNICALL Java_example_TestJNI_getNameForCPP
  (JNIEnv 
*  env, jobject)
{
    
// TODO 可以在此调用其他的代码
    std:: string  strName  =   " Tower " ;
    
return  env -> NewStringUTF(strName.c_str());
}


4) 编译CPP代码
命 令:g++ -o libtest.so -shared -I<include_path> -I<java_home>/include -I<java_home>/include/linux example_TestJNI.cpp

5)执行
package example;

public   class  Test  {
    
public   static   void  main(String[] args)  {
        TestJNI test 
=   new  TestJNI();
        System.
out .println( " Hello  "   +  test.getNameForCPP());
    }

}


export LD_EXPORT_PATH=<so_path>
java -cp <path> -Djava.library.path=<so_path> example.Test
输出:Hello Tower

export LD_EXPORT_PATH=.  当前路径
java -cp . -Djava.library.path=. example.Test

类和SO 文件都在当前目录,so的命名是lib***.so  比如libhello.so,
说明在java代码中载入的hello本地库


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics