本例子使用的操作系统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. 关于python中urllib.urlencode的时候出错:UnicodeEncodeError: ‘ascii’的记录

    原文我参见了:http://hi.baidu.com/setcookie/item/ddc6b694b1f13435336eeb3c 为毛我要费事的写下了,就是为了让自己记录一下,下面的也是直接摘录过 ...

  2. html 实体和htmlspecialchars()

    HTML 中的预留字符必须被替换为字符实体. HTML 实体 在 HTML 中,某些字符是预留的. 在 HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签. ...

  3. Eclipse上安装springsource-tool-suite

    spring tool suite 是一个基于eclipseIDE开发环境中的用于开发spring应用程序的工具.提供了开箱即用的环境用于实现,调试和部署你的spring应用,包括为关键的的服务器和云 ...

  4. C#中正则表达式编程(未完,待补充)

    对于只存储一个匹配,可用Match类: 一般模式: Regex reg = new Regex(string pattern); string str = "###############& ...

  5. iOS 解决上传100张图片内存奔溃问题

    最近项目需求,从相册中提取100张图片,然后上传到服务器.前提是图片不能压缩.因为要将图片信息采集出来制作出3D模型.所以必须是高清图片. 先看下代码 [NetWorking uploadWithUr ...

  6. 单机ZooKeeper配置

    1.创建zoo.cfg copy D:\zookeeper3.4.6\conf\zoo_sample.cfg zoo.cfg 修改追加如下内容 dataDir=D:/zookeeper3.4.6/da ...

  7. ubuntu创建Centos7镜像&&配置运行环境

    1. 下载centos7镜像 sudo docker pull centos:7 2. 启动centos7容器并挂载本地目录 sudo docker -it -v /home/software:/ho ...

  8. c# mysql and sqlserver数据库连接字符串

    .net 项目访问sqlserver 和mysql 两种数据库时,连接字符串有些不一样 具体配置如下 <connectionStrings> <add name="mysq ...

  9. 【老生常谈】Attr与Prop的区别

    “你为什么要做一个程序员?”,“因为我有一颗改变世界的心!”,“说人话”,“因为我没朋友...” -------------纯属娱乐 ================================= ...

  10. Intro to DBSCAN

    DBSCAN Density-Based Spatial Clustering of Application with Noise It can discover cluster of arbitra ...