原始出处http://blog.csdn.net/seker_xinjian/archive/2011/04/14/6323835.aspx

在进行Android NDK编程中,我们不可避免的要使用到JNI。JNI本质来讲是native代码(C++),它是托管程序集(Java语言编写的)与非托管程序集(C++语言编写的)的桥梁。要做到桥梁的作用,JNI就必须要求Java语言的代码和C++语言的代码在定义上要相互符合,否则上层应用调用底层实现的时候就找不到底层了。

例如,Java层定义了这样一个类:<root>/jni/Test1.java

[java] view plaincopy
  1. public class Test1
  2. {
  3. private static final float PI = 3.1415926f;
  4. private native void function1(int a);
  5. private native String function2();
  6. }

那么它的两个native函数所对应的native的定义必须如下:

[cpp] view plaincopy
  1. #undef Test1_PI
  2. #define Test1_PI 3.1415925f
  3. /*
  4. * Class:     Test1
  5. * Method:    function1
  6. * Signature: (I)V
  7. */
  8. JNIEXPORT void JNICALL Java_Test1_function1(JNIEnv *, jobject, jint);
  9. /*
  10. * Class:     Test1
  11. * Method:    function2
  12. * Signature: ()Ljava/lang/String;
  13. */
  14. JNIEXPORT jstring JNICALL Java_Test1_function2(JNIEnv *, jobject);

请注意它的C++层的函数定义的函数名、参数以及返回值的规范,不符合规范的函数定义,在java层调用就会出错了。如果初学者想要手动的写这种JNI函数的定义的话,确实应该非常的小心谨慎才行。

然而,JDK开发包中有一个小工具:javah,我们可以使用这个工具来自动生成Java层类对应的native层的函数定义。针对上面多提到的代码:<root>/jni/Test1.java,可以使用下面的命令行来操作:

>> cd <root>/jni/

>> javac Test1.java

>> javah Test1

这样就能生成一个Test1.h文件,打开该文件,我们就可以看到生成好的C++语言的函数定义。

虽然如此,我们在实际开发中还是会遇到一个问题:那就是Java包名对javah的要求。例如,我们定义一个类<root>/jni/com/test/Test2.java
[java] view plaincopy
  1. package com.test;
  2. public class Test2
  3. {
  4. private static final float PI = 3.1415926f;
  5. private native void function3(int a);
  6. private native String function4();
  7. }
如果我们依然使用上面的命令行,就无法生成相应的.h文件了。正确的方法如下:
>> cd <root>/jni/com/test/
>> javac Test2.java
>> javah -classpath <root>/jni/ com.test.Test2
或者
>> cd <root>/jni/
>> javac com/test/Test2.java
>> javah com.test.Test2
可见,如果Java类声明了包名,在使用javah的时候需要指明-classpath参数(默认为当前目录)
最终的头文件是com_test_Test2.h,我们还可以给javah传入 -o 参数,指定输出路径和目标文件名,如:
javah -o <root>/jni/com/Test2.h com.test.Test2
头文件的内容如下:
[cpp] view plaincopy
  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class com_test_Test2 */
  4. #ifndef _Included_com_test_Test2
  5. #define _Included_com_test_Test2
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. #undef com_test_Test2_PI
  10. #define com_test_Test2_PI 3.1415925f
  11. /*
  12. * Class:     com_test_Test2
  13. * Method:    function3
  14. * Signature: (I)V
  15. */
  16. JNIEXPORT void JNICALL Java_com_test_Test2_function3
  17. (JNIEnv *, jobject, jint);
  18. /*
  19. * Class:     com_test_Test2
  20. * Method:    function4
  21. * Signature: ()Ljava/lang/String;
  22. */
  23. JNIEXPORT jstring JNICALL Java_com_test_Test2_function4
  24. (JNIEnv *, jobject);
  25. #ifdef __cplusplus
  26. }
  27. #endif
  28. #endif

DNK编程 JNI 之 javah相关推荐

  1. 【混合编程jni 】第九篇之Jni总结

    系列目录:[混合编程Jni] 系列目录_香菜聊游戏的博客-CSDN博客 动态库的加载 可以使用标准 System.loadLibrary 从共享库加载原生代码. 关于参数传递 int.char 等这样 ...

  2. 【JNI】javah使用(初步)

    环境:window 7+ Eclipse 使用javah为已建立的Android工程创建头文件 已建立的工程目录大致如下: 其中MainActivity.java: package com.amand ...

  3. JNI_OnLoad 回调Java_Java本地接口(JNI)编程指南和规范(第八章)

    第八章 JNI的附加功能(Additional JNI Features) 我们已经讨论了JNI被使用来写本地方法和嵌入一个Java虚拟器实现到一个本地应用程序中的功能.这章介绍JNI剩余的功能. 8 ...

  4. Android Jni 调用

    Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 Chap 3:javah命令帮助信息... 16 Chap 4:用javah产生一个.h文件... 17 Chap5:j ...

  5. Android JNI --函数调用大全

    Chap1:JNI完全手册 最近在公司里做了一个手机的项目,需要JAVA程序在发送短信的时候和第三方的短信服务器连接.短信接口是用C++ 写的.琢磨了三天,大致搞懂了JNI的主体部分.先将心得整理,希 ...

  6. android中JNI知识(很全)

    Chap1:JNI完全手册 最近在公司里做了一个手机的项目,需要JAVA程序在发送短信的时候和第三方的短信服务器连接.短信接口是用C++写的.琢磨了三天,大致搞懂了JNI的主体部分.先将心得整理,希望 ...

  7. 【Android】JNI调用(完整版)

    原文出处:http://blog.csdn.net/kangyaping/article/details/6584027#t0 Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... ...

  8. JNI详解---从不懂到理解

     Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 Chap 3:javah命令帮助信息... 16 Chap 4:用javah产生一个.h文件... 17 Chap ...

  9. JNI_编程技术__网文整理

    Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 Chap 3:javah命令帮助信息... 16 Chap 4:用javah产生一个.h文件... 17 Chap5:j ...

  10. NDK JNI Android Studio开发与调试DEMO(三)(生成 .so 文件)

    Android Studio NDK 开发与调试(生成 .so 文件) 温馨提示:如果你的 Android Studio 版本在 3.0以上 , 建议你用 cMake /ndk-build 的新姿势进 ...

最新文章

  1. C++中fstream的使用
  2. 路由器中Rom/Ram/NVRAM/FLASH的区别
  3. js vm报错_uni-app v3版本更新常见问题排查
  4. mysql MHA 集群搭建
  5. juery的跨域请求2
  6. php mongo save,MongoDB:使用save()更新集合中的现有文档
  7. 国学能带给孩子什么?
  8. DEV MessageBox
  9. [家里蹲大学数学杂志]第039期高等数学习题集
  10. 什么是工序分析法?工序分析的方法和实施步骤有哪些
  11. 【机器学习】解释机器学习模型
  12. vb rs.recordCount=-1的解决办法
  13. facebook登陆授权 服务器接入记录
  14. 【网络实验箱02】-odl-neutron北向抓包分析
  15. 【Java例题】3.6 计算arcsin(x)的值
  16. wp缩略图php,wordpress缩略图彻底解决方法,自动获取第一张图片缩略图
  17. 浪潮服务器开机没有信号输出,PLC输出指示灯已经点亮但是输出没有信号-工业支持中心-西门子中国...
  18. 考试系统之选择题评分
  19. PTA(2019年天梯赛-全国总决赛)----彩虹瓶 (25分)
  20. maven引入lib下jar包的方式

热门文章

  1. 现在润新加坡是个好主意吗?
  2. mac android usb共享网络,mac 网络共享软件 手机usb共享网络方法和技巧详解介绍
  3. Unity RenderTexture实现 刮彩票、橡皮擦、擦除效果(3D物体)
  4. 优动漫PAINT实现制图化繁为简的一波骚操作
  5. 甘超波:NLP潜意识和意识
  6. 浏览器主页被篡改为hao123、360和2345解决办法
  7. 疫情下的大数据力量:多地政府借力大数据技术,多家企业上马大数据产品
  8. python3模拟键盘输入_python之模拟键盘
  9. mac废纸篓的如何还原?
  10. matlab对离散曲线积分,matlab实现曲线积分