浅试 JNI编程
好吧,开始我的第一个JNI试验小程序
HelloWorld.java 代码清单
public class HelloWorld {
static {
System.loadLibrary("HelloWorld");
}
public static native void hello(String msg);
public static void main(String args[]){
HelloWorld hw = new HelloWorld();
hw.Display();
}
void Display(){
System.out.println("hello,world");
}
}
记得文件名必须和类名一致,编译
javac HelloWorld
利用 javah 命令生成c 的头文件,命令形式 javah <packagename>.<classname>,因为我没有定义包名,所以直接是类名:
javah HelloWorld
这样在目录下将会生成以包名为文件名的头文件 HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */ #ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: hello
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_HelloWorld_hello
(JNIEnv *, jclass, jstring); #ifdef __cplusplus
}
#endif
#endif
下面我们需要建立HeloWorld的动态共享库,先创建一个HelloWorld.c, 然后将头文件中的函数定义拷贝过来,并且指定参数的变量名
#include "HelloWorld.h" JNIEXPORT void JNICALL Java_HelloWorld_hello(JNIEnv * env, jclass jz, jstring s)
{
}
这是个毫无用处的函数,在java程序中我们也只有声明,没有调用,现在我只是试验他是否能正常装载。用 gcc 命令进行编译:
gcc -I/usr/lib/jdk1.6.0_45/include -I/usr/lib/jdk1.6.0_45/include/linux -fPIC -c HelloWorld.c
gcc的 -I 选项指定头文件的搜索路径,jni.h 在jdk 的include子目录里,而jni_md.h在 include/linux下,所以要把这两个路径加入头文件的搜索路径。-c 选项指定生成 .o 文件,如果缺少 -c 选项gcc会自动链接生成可执行文件,因为在我们的程序中缺少 main 函数,所以会出现错误。另外我们希望生成的是动态链接库,所以我们不需要生成可执行文件,只要生成目标文件即可。经过执行上面的命令,在目录下会生成 HelloWorld.o
我们执行下面的命令生成动态链接库
gcc -shared -o libHelloWorld.so HelloWorld.o
-shared 指示生成共享库, 而 -o 可以指定生成的共享库的文件名,注意linux下共享库的命名是有讲究的,首先文件名必须由lib作为前缀,其次扩展名为.so, 而他们之间的名字应该和 System.loadLibrary调用指定的名字相符,而且大小写一致。
回头看看我们java文件中的代码片段:
public class HelloWorld {
static {
System.loadLibrary("HelloWorld"); // 会寻找 libHelloWorld.so 动态库
}
...
}
下一步使用java 命令运行我们的java程序:
java HelloWorld
会报告错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloWorld in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
at HelloWorld.<clinit>(HelloWorld.java:6)
Could not find the main class: HelloWorld. Program will exit.
这是因为java找不到我们的动态库。我们很奇怪的是明明动态库就在当前的目录下,而且文件的命名也符合标准,为何还找不到。这里的原因是java程序并非足够的智能,根据错误的提示可以知道我们可以通过设置 java.library.path 变量来指定库的搜索路径,好这样一来,问题就简单了,运行下面的命令,搞定:
java -Djava.library.path=. HelloWorld
通过将java.libray.path=. 来将java.libray.path设置为当前目录。
浅试 JNI编程的更多相关文章
- 在 JNI 编程中避免内存泄漏
JAVA 中的内存泄漏 JAVA 编程中的内存泄漏,从泄漏的内存位置角度可以分为两种:JVM 中 Java Heap 的内存泄漏:JVM 内存中 native memory 的内存泄漏. Java H ...
- NDK(22)JNI编程如何避免常见缺陷
转自 : http://www.ibm.com/developerworks/cn/java/j-jni/index.html 避免常见缺陷 假设您编写了一些新 JNI 代码,或者继承了别处的某些 J ...
- Android studio 下JNI编程实例并生成so库
Android studio 下JNI编程实例并生成so库 因为公司需要为Android相机做美颜等图像后期处理,需要使用JNI编程,最近学了下JNI,并且在Android Studio下实现了一个小 ...
- JNI编程(二) —— 让C++和Java相互调用(2)
3.getRamdomOrder() 这个方法会从backend得到一个随机的Order对象(抱歉这里“Random”拼错了),然后再调用java中相应的通知方法来通知foreground.getRa ...
- JNI编程(二) —— 让C++和Java相互调用(1)
自己在外面偷偷的算了下,又有将近两个月没更新过blog了.趁着今天有兴致,来更新JNI编程的第二篇文章.在第一篇里,大概介绍了JNI的特点.用途和优劣.并且做一个最简单的JNI的例子,不过说实话那个例 ...
- 【转】android JNI编程 一些技巧(整理)
原文网址:http://blog.csdn.net/linweig/article/details/5203716 本篇将介绍在JNI编程中如何传递参数和返回值. 首先要强调的是,native方法不但 ...
- Android中JNI编程的那些事儿(1)
转:Android中JNI编程的那些事儿(1)http://mobile.51cto.com/android-267538.htm Android系统不允许一个纯粹使用C/C++的程序出现,它要求必须 ...
- 【转】Android JNI编程—JNI基础
原文网址:http://www.jianshu.com/p/aba734d5b5cd 最近看到了很多关于热补的开源项目——Depoxed(阿里).AnFix(阿里).DynamicAPK(携程)等,它 ...
- java jni 编程
最近要学习Java JNI 编程. 我使用的是的windows系统.装了一个cygwin. 根据 <JNI 编程规范和指南>. 文件网址: http://wenku.baidu.com/v ...
随机推荐
- Cocos2d-x 学习资料推荐
最近在看Cocos2d-x ,官网的资料太少了,下面推荐一些比较好的教程,不断更新中. 1. cocos2d-x高级开发教程 如果你懂得objective-c 那么一定要看看这本书,这里面有许多C++ ...
- 中石油-高精度阶乘-java
问题 F: [高精度]高精度阶乘 时间限制: 1 Sec 内存限制: 64 MB提交: 49 解决: 13[提交][状态][讨论版] 题目描述 <魔法宝典>对于修罗王是如此重要,是因为 ...
- codeforces 486C. Palindrome Transformation 解题报告
题目链接:http://codeforces.com/problemset/problem/486/C 题目意思:给出一个含有 n 个小写字母的字符串 s 和指针初始化的位置(指向s的某个字符).可以 ...
- C++类的成员函数使用的一些小总结
From: http://blog.csdn.net/xiayefanxing/article/details/7607506 这一阵做项目代码开发的时候,用到了在一个C++文件中使用另一个类的成员函 ...
- 发现磁盘的shell
#!/bin/bash #set -x diskarray=(`cat /proc/diskstats |grep -E "\bsd[a-z]\b|\bxvd[a-z]\b|\bvd[a-z ...
- asp.net mvc int[] 和 string[] 自定义数组绑定
新建类,int[]数组模型绑定 using System; using System.Collections.Generic; using System.Linq; using System.Web; ...
- 学SEO你其实只需要半个钟
网站上线之前: 关键词的分析以及选择: 关键词在我们网站的每个页面:首页,栏目页,文章都存在,它定位了你的网站的这个页面是做什么的,有什么内容,也是SEO中的最重要的部分. 网站必须确定并且设置好关键 ...
- phpstorm 8 license key
Learn Programming===== LICENSE BEGIN =====63758-1204201000000Ryqh0NCC73lpRm!XVcxFChJ2gTUR2lZtlLXrPLb ...
- CI中REST URL含有中文怎么处理(报错:The URI you submitted has disallowed characters)
解决方法: 客户端在发送GET URL请求的时候,将含有中文的URL编码即可 比如: 原始:http://localhost/qk/rest/user_album_api/get_user_album ...
- DB,Cache和Redis应用场景分析
最近做一产品,微博方面的.数据存储同时用到了DB(mysql),Cache(memcache),Redis.其实最开始架构设计的时候是准备用MongoDB的,由于学习成本太高,最终选择放弃了,采用了比 ...