深入理解Android(2)——理解Android中的JNI(中)

在上一篇中我们了解了Android中有关JNI的使用,其实JNI是很早就有的,不是在Android创造的新技术,是SUN为我们提供的一种Java和本地代码之间相互调用的方法,这一篇我们来建立一个普通的Java工程来具体看一下Java中如何调用C/C++代码。

一、新建一个普通Java工程

  1. package com.csdn.test;  
  2.   
  3. /** 
  4.  * 阳光小强 http://blog.csdn.net/dawanganban 
  5.  * @author lixiaoqiang 
  6.  * 
  7.  */  
  8. public class TestJNI {  
  9.       
  10.     public native void saveHello();  
  11.   
  12.     public static void main(String[] args) {  
  13.         TestJNI jni = new TestJNI();  
  14.         jni.saveHello();  
  15.     }  
  16. }  
在TestJNI中我们声明了一个native方法。

二、生成C/C++头文件

SUN的JDK中已经为我们提供了一个生成对应C/C++头文件的工具(javah)

  1. lixiaoqiangdeMac-mini:bin lixiaoqiang$ whereis javah  
  2. /usr/bin/javah  
  3. lixiaoqiangdeMac-mini:bin lixiaoqiang$   
说明:我这里用的是max os系统,如果你是windows系统,在jdk目录下寻找。

找到我们工程文件所在的目录,执行javah命令如下:

  1. lixiaoqiangdeMac-mini:bin lixiaoqiang$ pwd  
  2. /Users/lixiaoqiang/Documents/AndroidWorkspace/TestJNI/bin  
  3. lixiaoqiangdeMac-mini:bin lixiaoqiang$ javah com.csdn.test.TestJNI  
  4. lixiaoqiangdeMac-mini:bin lixiaoqiang$ ls   
  5. com         com_csdn_test_TestJNI.h  
  6. lixiaoqiangdeMac-mini:bin lixiaoqiang$   
可以看到为我们生成了一个com_csdn_test_TestJNI.h的头文件

  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>  
  3. /* Header for class com_csdn_test_TestJNI */  
  4.   
  5. #ifndef _Included_com_csdn_test_TestJNI  
  6. #define _Included_com_csdn_test_TestJNI  
  7. #ifdef __cplusplus  
  8. extern "C" {  
  9. #endif  
  10. /* 
  11.  * Class:     com_csdn_test_TestJNI 
  12.  * Method:    saveHello 
  13.  * Signature: ()V 
  14.  */  
  15. JNIEXPORT void JNICALL Java_com_csdn_test_TestJNI_saveHello  
  16.   (JNIEnv *, jobject);  
  17.   
  18. #ifdef __cplusplus  
  19. }  
  20. #endif  
  21. #endif  

三、生成动态库文件

下面我们打开C/C++编辑器(我这里使用的时Xcode,在Windows平台上的朋友可以使用VisualStudio)

main.cpp中我们输出一行文字,如下:

  1. #include "com_csdn_test_TestJNI.h"  
  2. #include <iostream>  
  3. using namespace std;  
  4.   
  5. JNIEXPORT void JNICALL Java_com_csdn_test_TestJNI_saveHello(JNIEnv * evn, jobject obj){  
  6.     cout << "hello world" << endl;  
  7. }  
在编译的过程中会发现找不到jni.h和jni_md.h文件,这两个文件可以在JDK的include目录下找到,拷贝到工程中,下面将上面的工程导出动态链接库。

在导出链接库(编译)的时候在MacOS下和在Linux, Windows有所不同, 不是编译成.so或者dll, 而是MacOS自己的jnilib. 并且jni.h的目录也比较特殊, 是/System/Library/Frameworks/JavaVM.framework/Headers/, 这个需要稍微注意一下, 具体的命令如下:

  1. lixiaoqiangdeMac-mini:TestJNI lixiaoqiang$ g++ -dynamiclib -o libhelloworld.jnilib main.cpp -framework JavaVM -I/System/Library/Frameworks/JavaVM.framework/Headers  
  2. lixiaoqiangdeMac-mini:TestJNI lixiaoqiang$ ls  
  3. com_csdn_test_TestJNI.h jni_md.h        main.cpp  
  4. jni.h           libhelloworld.jnilib  
  5. lixiaoqiangdeMac-mini:TestJNI lixiaoqiang$   
可以看到在该目录生成了一个libhelloworld.jnilib文件,我们将该文件拷贝到我们Java工程的bin目录下(windows下是classes目录)

向Java工程中添加加装动态库的代码(下面的static语句块中的System.loadLibrary方法)

  1. package com.csdn.test;  
  2.   
  3. /** 
  4.  * 阳光小强 http://blog.csdn.net/dawanganban 
  5.  * @author lixiaoqiang 
  6.  * 
  7.  */  
  8. public class TestJNI {  
  9.       
  10.     public native void saveHello();  
  11.   
  12.     public static void main(String[] args) {  
  13.         TestJNI jni = new TestJNI();  
  14.         jni.saveHello();  
  15.     }  
  16.       
  17.     static{  
  18.         System.loadLibrary("helloworld");  
  19.     }  
  20. }  
最后将该库文件添加到Java程序可以访问的环境变量中就可以运行输出“helloworld"了。

下一篇文章我们将来看一下如何在C/C++中调用Java中的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值