JNI的一个简单实例
2017-04-11 09:53
197 查看
本例子使用的操作系统MacOS, 64位JVM。
JNI编写的几个步骤如下:
编写Java代码,并注明native方法:
其中声明displayHelloJni()方法为本地方法,在static静态块中用System.loadLibrary()加载本地库。
使用javac命令编译此java类:
利用javah命令生成C语言的头文件(.h文件)
执行完成后,就在执行路径下生成名称为com_xxx_clamaa_jni_HelloJni.h的头文件:
然后在同级的目录下新建一个HelloJniImpl.cpp文件,这个与HelloJni.java中定义的System.loadLibrary()的文件名一致。
编译C++代码的时候在MacOS下和在Linux Windows有所不同, 不是编译成.so或者dll, 而是MacOS自己的jnilib. 并且jni.h的目录也比较特殊, 是/System/Library/Frameworks/JavaVM.framework/Headers/,执行的命令g++,
编译完成后,就生成libhellojniimpl.jnilib文件,此时执行结果为:
生成的文件名称必须为: libhellojniimpl.jnilib,否则抛出异常:
如果设置成带参数的本地方法,那么生成的参数会多一个jstring
与原来的实现方式,调用方式都一样,这样简单的JNI实现就完成了。
如果我们在原来的cpp实现中加入一行抛出异常的代码:
那么在执行的过程中也会抛出对应的错误:
JNI编写的几个步骤如下:
编写Java代码,并注明native方法:
public class HelloJni { public native void displayHelloJni(); public static void main(String[] args) { HelloJni helloJni = new HelloJni(); helloJni.displayHelloJni(); } static { System.loadLibrary("HelloJniImpl"); } }
其中声明displayHelloJni()方法为本地方法,在static静态块中用System.loadLibrary()加载本地库。
使用javac命令编译此java类:
javac com/xxx/clamaa/jni/HelloJni.java
利用javah命令生成C语言的头文件(.h文件)
javah com.xxx.clamaa.jni.HelloJni
执行完成后,就在执行路径下生成名称为com_xxx_clamaa_jni_HelloJni.h的头文件:
#include <jni.h> /* Header for class com_xxx_clamaa_jni_HelloJni */ #ifndef _Included_com_xxx_clamaa_jni_HelloJni #define _Included_com_xxx_clamaa_jni_HelloJni #ifdef __cplusplus extern "C" { #endif /* * Class: com_yonyou_clamaa_jni_HelloJni * Method: displayHelloJni * Signature: ()V */ JNIEXPORT void JNICALL Java_com_xxx_clamaa_jni_HelloJni_displayHelloJni (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
然后在同级的目录下新建一个HelloJniImpl.cpp文件,这个与HelloJni.java中定义的System.loadLibrary()的文件名一致。
#include "com_xxx_clamaa_jni_HelloJni.h" #include <iostream> #include <jni.h> using namespace std; /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_com_xxx_clamaa_jni_HelloJni_displayHelloJni (JNIEnv *, jobject) { cout << "Hello Jni by clamaa!"; return; }
编译C++代码的时候在MacOS下和在Linux Windows有所不同, 不是编译成.so或者dll, 而是MacOS自己的jnilib. 并且jni.h的目录也比较特殊, 是/System/Library/Frameworks/JavaVM.framework/Headers/,执行的命令g++,
g++ -dynamiclib -o libhellojniimpl.jnilib HelloJniImpl.cpp -framework JavaVM -I/System/Library/Frameworks/JavaVM.framework/Headers
编译完成后,就生成libhellojniimpl.jnilib文件,此时执行结果为:
java com.xxx.clamaa.jni.HelloJni >Hello Jni by clamaa!
生成的文件名称必须为: libhellojniimpl.jnilib,否则抛出异常:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloJniImpl in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1119) at com.yonyou.clamaa.jni.HelloJni.<clinit>(HelloJni.java:16)
如果设置成带参数的本地方法,那么生成的参数会多一个jstring
Java_HelloWorld_print(JNIEnv *env, jobject obj, jstring str)
与原来的实现方式,调用方式都一样,这样简单的JNI实现就完成了。
如果我们在原来的cpp实现中加入一行抛出异常的代码:
cout << "Hello Jni by clamaa!"; throw 1; return;
那么在执行的过程中也会抛出对应的错误:
java com.yonyou.clamaa.jni.HelloJni >libc++abi.dylib: terminating with uncaught exception of type int >Hello Jni by clamaa!Abort trap: 6
相关文章推荐
- J2ME应用实例——一个简单的计算器实现(附源代码)
- 一个简单在jsp页面中连接sqlserver数据库的小实例
- 一个响应鼠标移动的简单实例!
- 跟一个从零开始学excel vba的新手的对话过程(简单程序实例)
- 一个简单的ajax实例
- 初学Attribute(一个简单实例)
- 一个简单分页的实例
- 最简单的一个堆栈溢出攻击实例 (1) [by Progsoft]
- 一个简单的linux下网络程序实例-网络编程入门
- SWT组件的生命周期(续一个简单的SWT程序实例及详解)
- 一个简单的SWT程序实例及详解
- 一个简单的EJB-Session Bean实例
- 一个简单在jsp页面中连接sqlserver数据库的小实例
- 一个简单的单例实例
- 一个最简单的Ajax实例(大部分是抄袭的)
- Struts学习总结(一个简单的struts实例)
- 如何实现一个简单的remoteing实例
- 一个最简单的AJAX实例及解析
- 一个简单的hibernate实例(之二)
- linux socke编程实例:一个简单的echo服务器程序(2)