在做NDKi开发时,我们已经拿到某个so库文件后,如何去写对应的jni接口呢?
首先在拿到so的库文件后必须清楚要调用里面的方法,还有拿到对应的头文件
以添加curl.so为例:
一、采用cmakelist.txt添加共享so库,编写CmakeList.txt
#添加我们编写生成的lib
add_library( my-lib
SHARED
src/main/cpp/myjni.cpp)
#添加curl.so
add_library(curl
SHARED
IMPORTED )
#设置curl的属性,指明curl.so的路径,根路径是cmakeList.txt所在的文件夹
set_target_properties(
curl
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/libcurl.so )
#拿到的curl.so的头文件
#指明头文件路径,不然会提示找不到 so 的方法
include_directories(src/main/cpp/curl)
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
#指向链接库,即把my-lib和curl都添加上
target_link_libraries( # Specifies the target library.
my-lib
curl
# Links the target library to the log library
# included in the NDK.
${log-lib} )
二、编写native
myjni.cpp
#include "curl/curl.h"//添加头文件
static jint curl_init(JNIEnv *env, jclass clazz)
{
jcurl_t *jcurl = NULL;
CURL *curl = curl_easy_init();//curl_easy_init是curl.so的方法
if (!curl) {
return (int)jcurl;
}
jcurl = (jcurl_t *) malloc(sizeof(jcurl_t));
if (jcurl) {
memset((void *)jcurl, 0, sizeof(jcurl_t));
jcurl->curl = curl;
} else {
curl_easy_cleanup(curl);
}
return 0;
}
static JNINativeMethod gMethods[] = {
{"curl_init", "()I", (void *)curl_init},
};
int JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv *env;
jclass clazz;
if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
clazz = (*env)->FindClass(env, CLASSNAME);//CLASSNAME是指向java的类,如:包/类名,类名不要写.java
if (clazz == NULL) {
LOGE("Can't find %s", CLASSNAME);
return -1;
}
if ((*env)->RegisterNatives(env, clazz, gMethods, ARRAY_SIZE(gMethods)) < 0) {
return -1;
}
(*env)->GetJavaVM(env, &vm);
return JNI_VERSION_1_6;
}
三、编写java层的native
MyNative.java
public static native curl_init();
static {
System.loadLibrary("my-lib");
}
编写完,就可以在需要的地方调用了...
更多精彩尽在公众号:Android全贯通