JNI的一个简单实例
本例子使用的操作系统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的一个简单实例的更多相关文章
- C++ 容器的综合应用的一个简单实例——文本查询程序
C++ 容器的综合应用的一个简单实例——文本查询程序 [0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例.通过实现一个简单的文本查 ...
- Ajax实现局部数据交互的一个简单实例
想要实现的功能:利用Ajax技术通过点击一个<button>按钮,然后在指定的文本框中输出想要的值. 1.使用Jsp创建一个前端页面. <body> <div style ...
- SpringMVC4+thymeleaf3的一个简单实例(篇一:基本环境)
首语:用SpringMVC和thymeleaf实现一个简单的应用,包括基本环境搭建,SpringMVC4和thymeleaf3的整合,页面参数的获取,页面参数验证,以及用MySQL保存数据.我会把步骤 ...
- MVC的一个简单实例
基本思路: 一个Regist.jsp注册页面,用于收集用户信息,发送请求给控制器Servlet:控制器层Servlet封装模型层对象 jBean,并调用其方法regiser实现用户信息的保存:模型层J ...
- Win32 API 多线程编程——一个简单实例(含消息参数传递)
Win32 API进行程序设计具有很多优点:应用程序执行代码小,运行效率高,但是他要求程序员编写的代码较多,且需要管理所有系统提供给程序的资源,要求程序员对Windows系统内核有一定的了解,会占用程 ...
- Android Studio1.4.x JNI开发基础 - 简单实例
接上一篇,搭建好基于Android Studio的环境之后,编写native代码相对来说也比较简单了.在Android上编写Native代码和在Linux编写C/C++代码还是有区别,Native代码 ...
- SpringMVC4+thymeleaf3的一个简单实例(篇五:页面和MySql的数据交互-展示以及存储)
这一篇将介绍怎样把页面数据保存的MySQL数据库,并将数据库内容展示到页面上.首先做一个基础工作,添加以下jar到lib:1: mysql-connector-Java-5.1.40-bin.jar ...
- SpringMVC4+thymeleaf3的一个简单实例(篇四:form表单数据验证)
关于表单数据验证有很多中方法,这里我仅介绍JSR303注解验证.JSR303仅仅是一个规范,这里我们要用到它的一个实现:hibernate-validator. 注意在spring的配置文件sprin ...
- SpringMVC4+thymeleaf3的一个简单实例(篇三:页面参数获取)
本篇将通过示例介绍页面参数是如何传递到后台的.我们继续沿用之前搭好的程序结构,如果你不知道,请参照前两篇.为方便跳转页面,我们在首页以及zoolist.html页面都加上彼此地址的链接:首页: zoo ...
随机推荐
- 关于python中urllib.urlencode的时候出错:UnicodeEncodeError: ‘ascii’的记录
原文我参见了:http://hi.baidu.com/setcookie/item/ddc6b694b1f13435336eeb3c 为毛我要费事的写下了,就是为了让自己记录一下,下面的也是直接摘录过 ...
- html 实体和htmlspecialchars()
HTML 中的预留字符必须被替换为字符实体. HTML 实体 在 HTML 中,某些字符是预留的. 在 HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签. ...
- Eclipse上安装springsource-tool-suite
spring tool suite 是一个基于eclipseIDE开发环境中的用于开发spring应用程序的工具.提供了开箱即用的环境用于实现,调试和部署你的spring应用,包括为关键的的服务器和云 ...
- C#中正则表达式编程(未完,待补充)
对于只存储一个匹配,可用Match类: 一般模式: Regex reg = new Regex(string pattern); string str = "###############& ...
- iOS 解决上传100张图片内存奔溃问题
最近项目需求,从相册中提取100张图片,然后上传到服务器.前提是图片不能压缩.因为要将图片信息采集出来制作出3D模型.所以必须是高清图片. 先看下代码 [NetWorking uploadWithUr ...
- 单机ZooKeeper配置
1.创建zoo.cfg copy D:\zookeeper3.4.6\conf\zoo_sample.cfg zoo.cfg 修改追加如下内容 dataDir=D:/zookeeper3.4.6/da ...
- ubuntu创建Centos7镜像&&配置运行环境
1. 下载centos7镜像 sudo docker pull centos:7 2. 启动centos7容器并挂载本地目录 sudo docker -it -v /home/software:/ho ...
- c# mysql and sqlserver数据库连接字符串
.net 项目访问sqlserver 和mysql 两种数据库时,连接字符串有些不一样 具体配置如下 <connectionStrings> <add name="mysq ...
- 【老生常谈】Attr与Prop的区别
“你为什么要做一个程序员?”,“因为我有一颗改变世界的心!”,“说人话”,“因为我没朋友...” -------------纯属娱乐 ================================= ...
- Intro to DBSCAN
DBSCAN Density-Based Spatial Clustering of Application with Noise It can discover cluster of arbitra ...