您的位置:首页 > 其它

JNI_OnLoad方法和RegisterNatives方法的结合

2016-05-23 16:53 471 查看
JNI_OnLoad方法和RegisterNatives方法的结合可以做到更佳方便的注册你的jni方法。

1.在C/C++文件中实现JNI_OnLoad方法。如下:

jint JNI_OnLoad(JavaVM* pVm, void* reserved) {
  //your method...
<span style="white-space:pre">	</span>return JNI_VERSION_1_6;
}
(一定要返回版本号,之前看别人博客时看到的,至于为什么,我也不清楚,猜测是C/C++方法中为了标记该方法的调用结果吧)。

2.赋值JNINativeMethod数组。JNINativeMethod是用来描述jni方法的结构。

typedef struct {
const char* name;
const char* signature;
void* fnPtr;
} JNINativeMethod;
       name :java中native方法名。

signature :java中name 方法的参数和返回值的描述。

         fnPtr :java中name方法在C/C++中的具体实现的方法指针。

3.在JNI_OnLoad中调用RegisterNatives方法,进行注册native方法。

下面是一段代码具体实现的例子:

jint JNI_OnLoad(JavaVM* pVm, void* reserved) {
JNIEnv* env;
if ((*pVm)->GetEnv(pVm, (void **)&env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
JNINativeMethod nm[8];
nm[0].name = "naInit";
nm[0].signature = "(Ljava/lang/String;)I";
nm[0].fnPtr = (void*)naInit;

nm[1].name = "naSetSurface";
nm[1].signature = "(Landroid/view/Surface;)V";
nm[1].fnPtr = (void*)naSetSurface;

nm[2].name = "naGetVideoRes";
nm[2].signature = "()[I";
nm[2].fnPtr = (void*)naGetVideoRes;

nm[3].name = "naSetup";
nm[3].signature = "(II)I";
nm[3].fnPtr = (void*)naSetup;

nm[4].name = "naPlay";
nm[4].signature = "()V";
nm[4].fnPtr = (void*)naPlay;

nm[5].name = "naStop";
nm[5].signature = "()V";
nm[5].fnPtr = (void*)naStop;

jclass cls = (*env)->FindClass(env, "roman10/tutorial/android_ffmpeg_tutorial02/MainActivity");
//Register methods with env->RegisterNatives.
(*env)->RegisterNatives(env, cls, nm, 6);
return JNI_VERSION_1_6;
}
例子出自 :http://pan.baidu.com/s/1gfjTq7L  原项目是在github上,一时找不到链接。这是我保存好的,没有修改。 里面有两个工程,第二个可以用。上面的代码是摘自第二个工程tutorial02.c中的代码。

结尾 :这种方式注册native方法很方便,更改C/C++文件和java文件都不需要用麻烦的javah去编译了。听说JNI_OnUnload方法还可以更改Framework层的模块。小白我还没有试呢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: