本例子使用的操作系统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

JNI的一个简单实例的更多相关文章

  1. C++ 容器的综合应用的一个简单实例——文本查询程序

    C++ 容器的综合应用的一个简单实例——文本查询程序 [0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例.通过实现一个简单的文本查 ...

  2. Ajax实现局部数据交互的一个简单实例

    想要实现的功能:利用Ajax技术通过点击一个<button>按钮,然后在指定的文本框中输出想要的值. 1.使用Jsp创建一个前端页面. <body> <div style ...

  3. SpringMVC4+thymeleaf3的一个简单实例(篇一:基本环境)

    首语:用SpringMVC和thymeleaf实现一个简单的应用,包括基本环境搭建,SpringMVC4和thymeleaf3的整合,页面参数的获取,页面参数验证,以及用MySQL保存数据.我会把步骤 ...

  4. MVC的一个简单实例

    基本思路: 一个Regist.jsp注册页面,用于收集用户信息,发送请求给控制器Servlet:控制器层Servlet封装模型层对象 jBean,并调用其方法regiser实现用户信息的保存:模型层J ...

  5. Win32 API 多线程编程——一个简单实例(含消息参数传递)

    Win32 API进行程序设计具有很多优点:应用程序执行代码小,运行效率高,但是他要求程序员编写的代码较多,且需要管理所有系统提供给程序的资源,要求程序员对Windows系统内核有一定的了解,会占用程 ...

  6. Android Studio1.4.x JNI开发基础 - 简单实例

    接上一篇,搭建好基于Android Studio的环境之后,编写native代码相对来说也比较简单了.在Android上编写Native代码和在Linux编写C/C++代码还是有区别,Native代码 ...

  7. SpringMVC4+thymeleaf3的一个简单实例(篇五:页面和MySql的数据交互-展示以及存储)

    这一篇将介绍怎样把页面数据保存的MySQL数据库,并将数据库内容展示到页面上.首先做一个基础工作,添加以下jar到lib:1: mysql-connector-Java-5.1.40-bin.jar ...

  8. SpringMVC4+thymeleaf3的一个简单实例(篇四:form表单数据验证)

    关于表单数据验证有很多中方法,这里我仅介绍JSR303注解验证.JSR303仅仅是一个规范,这里我们要用到它的一个实现:hibernate-validator. 注意在spring的配置文件sprin ...

  9. SpringMVC4+thymeleaf3的一个简单实例(篇三:页面参数获取)

    本篇将通过示例介绍页面参数是如何传递到后台的.我们继续沿用之前搭好的程序结构,如果你不知道,请参照前两篇.为方便跳转页面,我们在首页以及zoolist.html页面都加上彼此地址的链接:首页: zoo ...

随机推荐

  1. resizable可调整尺寸组件

    Resizable 可调整尺寸不依赖于其他组件 1.用法:通过标记创建可调整尺寸(resizable)对象 <div class="easyui-resizable" sty ...

  2. Java基础学习-内部类

    /*内部类: 成员内部类 局部内部类 匿名内部类*/ package insideclass; /*成员内部类: * 在类的成员位置,和成员变量,成员方法的位置是一样的. * 内部类可以直接访问为外部 ...

  3. 20165202 实验一 Java开发环境的熟悉

    一.实验内容及步骤 (一)使用JDK编译.运行简单的Java程序 建立"自己学号exp1"的目录 mkdir 20165202exp1 进入目录 cd 20165202exp1 在 ...

  4. EasyPusher/EasyDarwin支持H.265 RTSP/RTP直播推流与分发播放

    前言描述 随着大屏时代和高清时代的到来,人们已经不再满足于VGA.CIF这种小分辨率了,取而代之的是720P.1080P.4K级的视频传输,虽然我们国家的基础带宽一直在上升,但普遍情况下,传输高清视频 ...

  5. java未来发展方向!新手入门了解

    随社会信息的发展着,java广泛应用于PC.数据中心.游戏控制台.科学超级计算机.移动电话和互联网等行业.从目前的招聘量上看,对java开发人才需求量是很大的,而且未来的仍然是主流,就业前景很好.只要 ...

  6. JAVA多线程----用--取钱问题2

    在该示例代码中,TestAccount类是测试类,主要实现创建帐户Account类的对象,以及启动学生线程StudentThread和启动家长线程GenearchThread.在StudentThre ...

  7. 原生js实现div拖拽

    十分简单的效果. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...

  8. JS格式化数字(每三位加逗号)

    function toThousands(num) { var num = (num || 0).toString(), result = ''; //判断是否带小数点 if (num.split(' ...

  9. iPhone4s 9.2.1安装cydia(越狱)

    依据网上资料而来 主要就是上图视频中的6步骤选项,不要选错. 1.prepare for jailbreak 2.选择Accept 3. proceed with jailbreak 4.begin ...

  10. 网站使用QQ登录问题小结

    关于网站如何使用QQ登陆这个问题就不多说了,很简单,登陆connect.qq.com找到相应的SDK,下载下来,里面会有demo,将相应的appid,appkey和回调地址callback改成自己的就 ...