Android JNI栗子 这里留意以下部分:
- sMethods数组定义了所要注册的JNI函数。第一个参数“NativeAdd”指的是在java层调用的函数名,第二个“(II)I”指的是函数的类型,第三个“(jint *)NativeAdd”指的是实际的C++函数
- “cls = env->FindClass(“com/example/mycalljni/MainActivity”);
”对应于调用调用native函数的java类。如果是其它的java类调用的话,那么这里也需要更改。
从这里可以看出,间接注册和直接注册的最大区别在于C/C++函数名的不同。
#include "jni.h"
#include
jint NativeAdd(JNIEnv* env,jobject clazz,jint num_1,jint num_2)
{
return num_1 + num_2;
}
static JNINativeMethod sMethods[] = {
{"NativeAdd", "(II)I", (jint *) NativeAdd},
};
/* * JNI Initialization */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
JNIEnv *env = NULL;
int status;
jclass cls;
printf("%s: Loading start", __FUNCTION__);
printf("sMethods size : %d", sizeof(sMethods));
// Check JNI version
if (jvm->GetEnv((void **)&env, JNI_VERSION_1_6))
{
printf("JNI version mismatch error");
return JNI_ERR;
}
//Find the java class
cls = env->FindClass("com/example/mycalljni/MainActivity");
if(cls == NULL)
{
printf("Unable to find class android.os.Message");
}
//Registry the native method
env->RegisterNatives(cls,sMethods,sizeof(sMethods) / sizeof(sMethods[0]));
return JNI_VERSION_1_6;
}
关键点
在本小节当中,我们不妨来看一下,哪些关键点在Java层是与JNI有关的。
- native
在Java代码中,只要是用native进行修饰的函数,都是本地函数,是直接调用到C/C++代码中的。只不过在Java里面比较幸福,只需要在一个函数中声明native即可,更多的参数匹配都是在C/C++进行的。 - System.loadLibrary(string libName)
功能:用于加载具体实现本地方法的C运行库
这里需要注意的是,即使传入的参数相同,但在不同平台中最后加载的运行库也是不同的。比如说,我们传入一个名为“hellojni”的字符串,实际加载的C运行库在Windows环境下是“hellojni.dll”,但在Linux下则是“libhellojni.so”了。
Android.mk解析可以阅读我博客中有关Android.mk的文章。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyJni
LOCAL_SRC_FILES := myjni.cpp include
$(BUILD_SHARED_LIBRARY)