深入理解Android(2)——理解Android中的JNI(中)
阳光小强参加了CSDN博客之星评选,如果你觉得阳光小强的博客对你有所帮助,为小强投上一票吧:http://vote.blog.csdn.net/blogstar2014/details?username=lxq_xsyu#content
在上一篇中我们了解了Android中有关JNI的使用,其实JNI是很早就有的,不是在Android创造的新技术,是SUN为我们提供的一种Java和本地代码之间相互调用的方法,这一篇我们来建立一个普通的Java工程来具体看一下Java中如何调用C/C++代码。
一、新建一个普通Java工程
package com.csdn.test; /**
* 阳光小强 http://blog.csdn.net/dawanganban
* @author lixiaoqiang
*
*/
public class TestJNI { public native void saveHello(); public static void main(String[] args) {
TestJNI jni = new TestJNI();
jni.saveHello();
}
}
在TestJNI中我们声明了一个native方法。
二、生成C/C++头文件
SUN的JDK中已经为我们提供了一个生成对应C/C++头文件的工具(javah)
lixiaoqiangdeMac-mini:bin lixiaoqiang$ whereis javah
/usr/bin/javah
lixiaoqiangdeMac-mini:bin lixiaoqiang$
说明:我这里用的是max os系统,如果你是windows系统,在jdk目录下寻找。
找到我们工程文件所在的目录,执行javah命令如下:
lixiaoqiangdeMac-mini:bin lixiaoqiang$ pwd
/Users/lixiaoqiang/Documents/AndroidWorkspace/TestJNI/bin
lixiaoqiangdeMac-mini:bin lixiaoqiang$ javah com.csdn.test.TestJNI
lixiaoqiangdeMac-mini:bin lixiaoqiang$ ls
com com_csdn_test_TestJNI.h
lixiaoqiangdeMac-mini:bin lixiaoqiang$
可以看到为我们生成了一个com_csdn_test_TestJNI.h的头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_csdn_test_TestJNI */ #ifndef _Included_com_csdn_test_TestJNI
#define _Included_com_csdn_test_TestJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_csdn_test_TestJNI
* Method: saveHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_csdn_test_TestJNI_saveHello
(JNIEnv *, jobject); #ifdef __cplusplus
}
#endif
#endif
三、生成动态库文件
下面我们打开C/C++编辑器(我这里使用的时Xcode,在Windows平台上的朋友可以使用VisualStudio)
main.cpp中我们输出一行文字,如下:
#include "com_csdn_test_TestJNI.h"
#include <iostream>
using namespace std; JNIEXPORT void JNICALL Java_com_csdn_test_TestJNI_saveHello(JNIEnv * evn, jobject obj){
cout << "hello world" << endl;
}
在编译的过程中会发现找不到jni.h和jni_md.h文件,这两个文件可以在JDK的include目录下找到,拷贝到工程中,下面将上面的工程导出动态链接库。
在导出链接库(编译)的时候在MacOS下和在Linux, Windows有所不同, 不是编译成.so或者dll, 而是MacOS自己的jnilib. 并且jni.h的目录也比较特殊, 是/System/Library/Frameworks/JavaVM.framework/Headers/, 这个需要稍微注意一下, 具体的命令如下:
lixiaoqiangdeMac-mini:TestJNI lixiaoqiang$ g++ -dynamiclib -o libhelloworld.jnilib main.cpp -framework JavaVM -I/System/Library/Frameworks/JavaVM.framework/Headers
lixiaoqiangdeMac-mini:TestJNI lixiaoqiang$ ls
com_csdn_test_TestJNI.h jni_md.h main.cpp
jni.h libhelloworld.jnilib
lixiaoqiangdeMac-mini:TestJNI lixiaoqiang$
可以看到在该目录生成了一个libhelloworld.jnilib文件,我们将该文件拷贝到我们Java工程的bin目录下(windows下是classes目录)
向Java工程中添加加装动态库的代码(下面的static语句块中的System.loadLibrary方法)
package com.csdn.test; /**
* 阳光小强 http://blog.csdn.net/dawanganban
* @author lixiaoqiang
*
*/
public class TestJNI { public native void saveHello(); public static void main(String[] args) {
TestJNI jni = new TestJNI();
jni.saveHello();
} static{
System.loadLibrary("helloworld");
}
}
最后将该库文件添加到Java程序可以访问的环境变量中就可以运行输出“helloworld"了。
下一篇文章我们将来看一下如何在C/C++中调用Java中的方法
最新文章
- 精通css 高级web标准解决方案——可视化格式模型-定位模型
- 在github上写个人简历——先弄个主页
- 自制简单实用IoC
- mount --bind 重启后失效的解决办法
- iconv 文件编码相互转换
- Ajax入门
- 【转】Java 类的生命周期详解
- 用wpf实现了多个excel文件的合并
- C#:ref和out的联系及区别
- redis和ehcache
- UVA 12545 Bits Equalizer
- 如果有三个Bool型变量,请写出一程序得知其中有2个以上变量的值是true
- NSOperation 的使用(下载相关) 图片和文件都是能够的 断点续传 图片逐渐显示
- Java并发工具类 - CountDownLatch
- jquery中this和event.target的区别
- 笔记:Spring Cloud Eureka 服务发现与消费
- G - SDOI
- 操作系统中的IPC机制(inter-process Communication)
- 使用R语言的RTCGA包获取TCGA数据--转载
- ";上市时间:&;nbsp;2014&;#24180;&;#31179;&;#20908;&;#23395;"; unicode十进制编码转中文
热门文章
- PostgreSQL Replication之第九章 与pgpool一起工作(1)
- c# 之抽象属性
- tf.cast(ndarray,dtype)
- linux 常用文本操作相关命令
- Git强制覆盖master分支
- CF983E NN country(倍增,差分)
- HNU 12886 Cracking the Safe 二十四点的判断
- 【Codeforces Round #422 (Div. 2) D】My pretty girl Noora
- IPMI远程管理一点记录
- Android页面事件挂接模拟