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 ...
随机推荐
- ExpandoObject使用
//public class Users { // public int Id { set; get; } // public string UName { set; get; } // public ...
- 记用ajax网页跳转大坑——后台执行了,但是没有跳转
搭建javaweb服务器的时候,把jsp文件放在WEB-INF目录下面,因为超链接不能所有只能通过拦截器,用do方法跳转 controller写的是对的: @Controller public cla ...
- L163
Chickens slaughtered in the United States, claim officials in Brussels, are not fit to grace Europea ...
- TeamView
1.TeamView TeamViewer是一个能在任何防火墙和NAT代理的后台用于远程控制,桌面共享和文件传输的简单且快速的解决方案.为了连接到另一台计算机,只需要在两台计算机上同时运行 TeamV ...
- 将glassfish 添加到服务中 ,自启
将glassfish 添加到服务中 ,自启. 命令: sc create wuziServer binPath= D:\wuzi\wuzi-start.bat start= auto
- 在ROS Kinetic和Gazebo 8中使用智能汽车仿真演示
在ROS Kinetic和Gazebo 8中使用智能汽车仿真演示 智能车无人驾驶技术是目前人工智能和机器人技术的研究热点,有许多开源平台可以使我们零基础零成本入门无人驾驶技术.本文分享一下目前ROS官 ...
- FTRL笔记
这篇笔记主要参考冯杨的五篇博客:在线最优化求解(Online Optimization).因为对于在线学习方法,稀疏性问题需要特别关注:每次在线学习一个新 instance 的时候,优化方向并不一定是 ...
- BZOJ4373 算术天才⑨与等差数列 【线段树】*
BZOJ4373 算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k ...
- BZOJ1001 BeiJing2006 狼抓兔子 【网络流-最小割】*
BZOJ1001 BeiJing2006 狼抓兔子 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较 ...
- vector 中的clear()
为什么clear之后,还是输出fdsafdsa.有什么办法可以真正清空之? 因为对于vector,clear并不真正释放内存(这是为优化效率所做的事),clear实际所做的是为vector中所保存的所 ...