设为首页 收藏本站
查看: 1075|回复: 0

[经验分享] Linux下 JNI的使用

[复制链接]

尚未签到

发表于 2018-5-25 12:00:38 | 显示全部楼层 |阅读模式
转载:http://www.cnblogs.com/bastard/archive/2012/05/17/2506877.html
Linux下 JNI的使用
什么是JNI
   JNI是Java native interface的简写,可以译作Java原生接口。Java可以通过JNI调用C/C++的库,这对于那些对性能要求比较高的Java程序无疑是一个福音。JNI是Java与C/C++交互的接口。
   使用JNI也是有代价。大家都知道JAVA程序是运行在JVM之上的,可以做到平台无关。但是如果Java程序通过JNI调用了原生的代码(比如c/c++等),则Java程序就丧失了平台无关性。
代码实例

   下面以HelloWorld的实现学习Linux下 JNI的使用。
第一步:创建一个 TestJni.java文件
DSC0000.gif
import java.util.*;publicclass TestJni{   //声明原生函数:参数为String类型publicnativevoid print(String content);   //加载本地库代码   static   {      System.loadLibrary("TestJni");   }}




编译 TestJni.java文件:javac TestJni.java
在当前文件夹下生成TestJni.class文件
注意print方法的声明,关键字native表明该方法是一个原生代码实现的。
另外注意static代码段的System.loadLibrary调用,这段代码表示在程序加载的时候,自动加载libTestJni.so库。

第二步:生成 TestJni.h文件
执行命令:javah -jni TestJni
生成TestJni.h文件

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class TestJni */#ifndef _Included_TestJni#define _Included_TestJni#ifdef __cplusplusextern"C" {#endif/* * Class:   TestJni * Method:  print * Signature: (Ljava/lang/String;)V */JNIEXPORT void JNICALL Java_TestJni_print (JNIEnv *, jobject, jstring);#ifdef __cplusplus}#endif#endif



该文件中包含了一个函数Java_TestJni_print的声明。这里面自动包含两个参数,非常重要。JNIEnv *和 jobject

第三步:创建TestJni.c文件

#include <jni.h>#include <stdio.h>#include <TestJni.h>JNIEXPORT void JNICALL   Java_TestJni_print(JNIEnv *env,jobject obj, jstring content){   // 从 instring 字符串取得指向字符串 UTF 编码的指针   //注意C语言必须(*env)->     C++ env->const jbyte *str =      (const jbyte *)(*env)->GetStringUTFChars(env,content, JNI_FALSE);    printf("Hello---->%s\n",str);
// 通知虚拟机本地代码不再需要通过 str 访问 Java 字符串。  (*env)->ReleaseStringUTFChars(env, content, (constchar *)str );  return;}




//这里看到 JNIEnv作用了,使得我们可以使用Java的方法
//jobject 指向在此 Java 代码中实例化的 Java 对象 LocalFunction 的一个句柄,相当于 this 指针
参数类型 jstring 对应java中的String,这里是有所不同的。每一个Java里的类型这里有对应的与之匹配。

命令行输入:
cc   -I/usr/lib/jvm/java-6-sun/include/linux/ 
      -I/usr/lib/jvm/java-6-sun/include/
  -I/home/xmp/AndroidProject/apk/JNI
  -fPIC -shared -o libTestJni.so TestJni.c
生成:libTestJni.so库文件



  在当前目录生成libTestJni.so。注意一定需要包含Java的include目录(请根据自己系统环境设定),
因为libTestJni.c中包含了jni.h。另外一个值得注意的是在libTestJni.java中我们LoadLibrary方法加载的是“TestJni”,
可我们生成的Library却是libTestJni。这是Linux的链接规定的,
一个库的必须要是:lib+库名+.so。链接的时候只需要提供库名就可以了

  -I/home/xmp/AndroidProject/apk/JNI 是我自己的练习目录也必须包含,否则.c文件中会找不到TestJni.h头文件。
  现在 liblibTestJni.so就是一个可以使用的库了,其功能就是有一个print函数 与刚才所创建的TestJni.java文件对应,
TestJni.java类中加载库liblibTestJni.so,声明了其函数print。所以现在TestJni.java中具备使用print函数的功能;
所以现在我们就可以通过使用TestJni.java来使用调用C库libTestJni.so中的函数

当然现在任何java类都可已加载liblibTestJni.so库来使用其中的功能。



第四步:
   创建HelloWord.java函数

import java.util.*;publicclass HelloWorld{   publicstaticvoid main(String argv[])   {     new HelloWorld();   }   public HelloWorld()   {     new TestJni().print("Hello,World !"); //调用TestJni的原生函数print   }}




输入命令编译: javac HelloWorld.java
生成HelloWorld.class

第五步:
   运行HelloWorld程序
命令行输入:java HelloWorld
输出结果:Hello---->Hello,World !
验证OK!

如果你这步发生问题,如果这步你收到java.lang.UnsatisfiedLinkError异常,可以通过如下方式指明共享库的路径:
java -Djava.library.path='.' HelloWorld

或者输入命令:
export LD_LIBRARY_PATH=“HelloWorld路径”:$LD_LIBRARY_PATH  设置环境变量
然后再 java HelloWorld 一样OK

简单例子,照着以下参考文档即可实现。

参考文档:
http://my.unix-center.net/~Simon_fu/?p=359
http://www.ibm.com/developerworks/cn/java/l-linux-jni/
JNIEnv功能参考:
http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-480981-1-1.html 上篇帖子: linux 时间修改 及 同步 下篇帖子: linux下使用goagent
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表