本例子使用的操作系统MacOS, 64位JVM。

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

最新文章

  1. asp.net mvc4 学习笔记一(基本原理)
  2. python 默认全局变量
  3. Rock-Paper-Scissors Tournament[HDU1148]
  4. 跟随标准与Webkit源码探究DOM -- 获取元素之getElementsByClassName
  5. Python 类的一些BIF
  6. 静态化 - 伪静态技术(Apache Rewrite 实现)
  7. sudo密码错误的解决办法
  8. cas 代理认证配置
  9. 【面试题】由HashMap引发的一系列追问
  10. [HNOI2012]与非
  11. UE4分支的Git Flow
  12. 集合转数组的toArray()和toArray(T[] a)方法
  13. 理解Python的双下划线命名(转)
  14. filebeat配置文件
  15. java基本知识归集
  16. [APIO2013]机器人[搜索、斯坦纳树]
  17. BZOJ2924 : [Poi1998]Flat broken lines
  18. 二.jquery.datatables.js表格数据添加
  19. java-JProfiler(三)-进行本地JVM的性能监控-监视本地java程序
  20. asp.net mvc Route路由映射.html后缀 404错误

热门文章

  1. 学会使用Fidder抓取app的http请求(转)
  2. web服务器无法显示font-awesome字体图标
  3. APUE学习笔记——8.1-8.4 进程基础
  4. Myeclipse WEB工程JSP使用JNDI 数据库连接池连接Mysql数据库
  5. Iphone 消息通知(APNS)的3种方式 -- C# 和 nodejs
  6. 利用pandas随机切分csv文件
  7. 设计模式 - 代理模式(Proxy Pattern)
  8. java未来发展方向!新手入门了解
  9. 原 the app referencesnon-public selectors in payload
  10. linux命令-xz