JNI使用说明

我们知道都c/c++的方法运行的效率,大部分情况下都比java的方法运行的效率都要高,而且在Android直播项目中就需要使用很多开源的库,比如rtmp,x264, ffmpeg等,这些都是c/c++进行编写的,所以要借助Java Native Interface 来调用这些开源库 。

于是我就一口气将JNI的官方文档都看了一遍,更有了以下的疑问

  1. Java如何调用c/c++方法

  2. c++线程如何调用java的静态和非静态方法

  3. c++如何更改java的静态和非静态的变量

  4. c++如何使用java的反射机制

  5. c++如何生成java变量并且返回

  6. jni方法使用的时候会出现异常,怎么捕获呢?

以下是上述的问题的解答

  1. Java如何调用c/c++方法?

1.2在Java的方法前添加修饰符native,则表示该方法作为java作为c/c++接口的方法。

1.2 通过控制台进入到工程源码的目录(一般到src的目录下),输入命令行 javah -jni classpath(com/example/jniexample/JNIMethodTest),在当前目录下生产对应的头文件com_example_jniexample_JNIMethodTest.h也可以通过自己编写对应的头文件

#ifndef COM_EXAMPLE_JNIEXAMPLE_JNIMETHODTEST_H 
#define COM_EXAMPLE_JNIEXAMPLE_JNIMETHODTEST_H

extern "C"{
   //假如在cpp中编译的话需要使用该关键字修饰
   
JNIEXPROT jstring JNICALL Java_com_example_jniexample_JNIMethodTest(JNIEnv *env, jobject jobz);//需要注意的是static方法第二个参数的是jclass,非static方法jobject
}

#endif

1.3 编写对应的c/cpp文件,引入这个头文件,并且实现头文件的里面的方法

#include "com_example_jniexample_JNIMethodTest.h"

extern "C"{
   
   
JNIEXPROT jstring JNICALL Java_com_example_jniexample_JNIMethodTest(JNIEnv *env, jobject jobz){
   
    return env->NewStringUTF("hello i am from c++");
}
}

1.4 在Android Studio使用CMake编译工具,或者是在eclipse使用ndk-build编译工具(这个CMake和ndk-build后面详细介绍)

1.5 在对应的编译工具就会生产对应的动态库,java的方法中就通过System.loadLibrary(“jmethodtest-jni”)来加载动态库,假如生产的动态库出现链接有问题,报某个函数找不到,则通过NDK中的程序 arm-linux-androideabi-objdump来将动态库中的函数都打印出来

$:arm-linux-androideabi-objdump -tT /Users/cwl/Developer/workspace/plugin/JNIExample/libs/armeabi-v7a/libhello-jni.so

//生成类似_ZN7_JNIEnv9NewObjectEP7_jclassP10_jmethodIDz这样子的代码我们根本无法理解,那么通过c++filt 来转换对应的函数

$:++filt -n _ZN7_JNIEnv9NewObjectEP7_jclassP10_jmethodIDz
$:_JNIEnv::NewObject(_jclass*, _jmethodID*, ...)//转换后可读的函数

1.6 然后在代码中调用这个Java的方法,则第一个问题解决。

问题1 的扩展:c++的方法一定要定义成JNIExport JNICALL <Javacom_xxx_xxx_xxx_MethodName>();有没有其他方法来注册动态的注册这些方法。

答:是有的,通过JNIEnv::RegisterNatives(jclass, JNINativeMethods,jint)来动态注册这样的方法。

/*通过Jni_onLoad在每一个so库中只有一个,并且可以在这个Jni_onLoad方法中动态的注册jni的方法,通过*/
JNIEXPROT jint JNICALL Jni_onLoad (JavaVM* vm, void *reserved){
   
JNIEnv* env = NULL
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值