本例子使用的操作系统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. 海康威视 嵌入到web页面相关问题

    因项目上面需求,接触到了海康威视的设备,要把他嵌入到web页面中,所以就开始了爬坑之路 刚开始不知道如何把设备的页面嵌入到项目的web页面中,直到我遇见了他——“WEB3.0控件开发包V1.0.9_C ...

  2. elasticsearch关于索引切分的实现

    [背景信息] ES一直以来对于已经创建好的索引的分片是不可以进行分割的,简单的说,当你创建了一个索引,并指定了number_of_shards为2,当随着数据量的不断增大,是无法将索引的shard扩充 ...

  3. weblogic启动失败java.lang.NullPointerException

    在weblogic 启动的时候 出现 java.lang.NullPointerException at weblogic.deploy.internal.adminserver.Deployment ...

  4. 配置mysql 允许远程连接

    今天折腾了好常时间远程连接mysql ,在云服务器里面打开了3306端口,使用了service mysql status查看到mysql进程正常. netstat -anp | grep mysql ...

  5. 关于Spinlock机制的一点思考

    存在两段代码同时在多核上执行的情况,这时候才需要一个真正的锁来宣告代码对资源的占有. 几个核可能会同时access临界区,这时的spinlock是如何实现的呢? 要用到CPU提供的一些特殊指令,对lo ...

  6. (转)MapReduce Design Patterns(chapter 3 (part 1))(五)

    Chapter 3. Filtering Patterns 本章的模式有一个共同点:不会改变原来的记录.这种模式是找到一个数据的子集,或者更小,例如取前十条,或者很大,例如结果去重.这种过滤器模式跟前 ...

  7. 激活函数之softmax介绍及C++实现

    下溢(underflow):当接近零的数被四舍五入为零时发生下溢.许多函数在其参数为零而不是一个很小的正数时才会表现出质的不同.例如,我们通常要避免被零除或避免取零的对数. 上溢(overflow): ...

  8. VS2013 tips

    1.创建一个connection时会自动产生一个localdb数据库文件,可以通过Server Explorer窗口查看这个localDB,注意,是Server Explorer窗口,而不是SQL S ...

  9. webdriver元素定位

    #1 通过id定位 driver.find_element_by_id("pop_setting_save").click() #2 通过name定位 driver.find_el ...

  10. selenium python实例脚本1

    #!/usr/local/bin/python3 # coding=utf-8 #统一编码from selenium import webdriverfrom time import sleep#im ...