在linux下进行JNI开发

前期准备:

1、Java JDK

2、gcc

3、g++

注意:gcc和g++的版本号要一致:如下:

[qiaoning@qiaoning ~]$ gcc --version gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2) Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [qiaoning@qiaoning ~]$ g++ --version bash: g++: command not found... [qiaoning@qiaoning ~]$ gcc --version gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2) Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
linux(Fedora) 安装gcc yum install gcc 安装g++ yum install gcc-c++

确保上述准备工作完成后开始下边的工作:

Java代码:

public class Hello { static { try { System.loadLibrary("hello"); } catch (UnsatisfiedLinkError e) { e.printStackTrace(); } } public Hello() {}; public native void SayHello(String strName); }在终端输入 javac Hello.java 后生成Hello.class 文件

然后:javah Hello 生成 Hello.h文件


然后在相同的目录下新建一个Hello.cpp文件:内容如下:

#include "Hello.h" #include <stdio.h> // 与 Hello.h 中函数声明相同 JNIEXPORT void JNICALL Java_Hello_SayHello (JNIEnv * env, jobject arg, jstring instring) { // 从 instring 字符串取得指向字符串 UTF 编码的指针 const jbyte *str = (const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE ); printf("Hello,%s\n",str); // 通知虚拟机本地代码不再需要通过 str 访问 Java 字符串。 env->ReleaseStringUTFChars( instring, (const char *)str ); return; }


接下来编译生成共享库:

gcc -I/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/include -I/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/include/linux -fPIC -c Hello.cpp 注意:这儿可能产生的错误:

1、

gcc: error trying to exec 'cc1plus': execvp: No such file or directory
原因:没有安装g++,或者gcc和g++的版本不一致

2、

/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0 根据自己机器实际的目录做相应的调整
编译成功后生成Hello.o
gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 Hello.o 
此命令生成 生成 libhello.so.1.0
 

 

接下来将生成的共享库拷贝为标准文件名

cp libhello.so.1.0 libhello.so

最后通知动态链接程序此共享文件的路径。

export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH

最后是java测试代码:
public class ToSay { public static void main(String argv[]) { ToSay say = new ToSay(); } public ToSay() { Hello h = new Hello(); // 调用本地方法向 John 问好 h.SayHello("John"); } }
用 javac 编译 ToSay.java,生成 ToSay.class
向执行普通 Java 程序一样使用 java ToSay,我们会看到在屏幕上出现 Hello,John。


 
  

应用中注意事项:

1 . 如果可以通过 TCP/IP 实现 Java 代码与本地 C/C++ 代码的交互工作,那么最好不使用以上提到的 JNI 的方式,因为一次 JNI 调用非常耗时,大概要花 0.5 ~ 1 个毫秒。

2 . 在一个 Applet 应用中,不要使用 JNI。因为在 applet 中可能引发安全异常。

3 . 将所有本地方法都封装在单个类中,这个类调用单个 DLL。对于每种目标操作系统,都可以用特定于适当平台的版本替换这个 DLL。这样就可以将本地代码的影响减至最小,并有助于将以后所需的移植问题包含在内。

4 . 本地方法要简单。尽量将生成的 DLL 对任何第三方运行时 DLL 的依赖减到最小。使本地方法尽量独立,以将加载 DLL 和应用程序所需的开销减到最小。如果必须要运行时 DLL,则应随应用程序一起提供它们。

5 . 本地代码运行时,没有有效地防数组越界错误、错误指针引用带来的间接错误等。所以必须保证保证本地代码的稳定性,因为,丝毫的错误都可能导致 Java 虚拟机崩溃。

参考链接:http://www.ibm.com/developerworks/cn/java/l-linux-jni/

 
上一篇: android按钮被点击文字颜色变化效果
1
0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值