在NDK开发中引入第三方库(AndroidStudio Cmake)

来源:互联网 发布:尼泊尔弯刀数据图纸 编辑:程序博客网 时间:2024/05/21 10:00


原文:http://blog.csdn.net/mxw3755/article/details/56676923
官方:https://developer.android.com/studio/projects/add-native-code.html#specify-abi
在NDK中可能需要复用之前已经编译好的so文件,所以本章的目标是给一个之前编译好的so文件外加一个需要调用接口的头文件,在现在项目中复用。

在本次实践过程中,已经有编译完成的各种cpu架构的libstringutil-lib.so以及头文件,Stringutil.h
头文件中简单定义了两个接口:
class StringUtil {
public:
static char* toLower(char* chars);
static char* toUpper(char* chars);
};
顾名思义上述接口已在libstringutil-lib.so中实现

现有工程需要调用这些接口,步骤如下:
1、在java层创建native接口
package dev.mars.jnidemo;public class StringUtils {    static {        System.loadLibrary("native-lib");    }    public static native String toLower(String str);    public static native String toUpper(String str);}



2、由Android Studio自动生成native层接口定义,native-lib是实现接口的cpp文件:
extern "C" {JNIEXPORT jstring JNICALLJava_dev_mars_jnidemo_StringUtils_toLower(JNIEnv *env, jclass type, jstring str_) {    const char *str =  env->GetStringUTFChars(str_, 0);    char* str2 =new char[strlen(str)];    strcpy(str2,str);    StringUtil::toLower(str2);    return env->NewStringUTF(str2);}JNIEXPORT jstring JNICALLJava_dev_mars_jnidemo_StringUtils_toUpper(JNIEnv *env, jclass type, jstring str_) {    const char *str =  env->GetStringUTFChars(str_, 0);    char* str2 =new char[strlen(str)];    strcpy(str2,str);    StringUtil::toUpper(str2);    return env->NewStringUTF(str2);}
}


此时编译器应该找不到StringUtil的定义,因此需要将Stringutil.h拷贝到cpp文件所在的文件夹下,本工程中如图所示,新建一个include文件夹,将头文件拷贝过去:
然后在native-lib.cpp中加入头文件的引用:

#include <string>#include <android/log.h>#include "include/StringUtil.h"


3、将所有so文件拷贝到工程的libs/jni目录下

4、修改app下的gradle文件,在android{}中加入如下代码,将so文件作为引用
sourceSets {    main {        jniLibs.srcDirs = ['./libs/jni']    }}

5、下面是最为关键的CmakeLists.txt的配置

cmake_minimum_required(VERSION 3.4.1)#定义变量ProjectRoot为工程根目录,用相对路径没通过编译,可能是路径写错,以后再试#本次使用绝对路径作为参数set(ProjectRoot G:/AndroidStudioProjects/JNIDemo)#将native-lib加入到编译源中add_library( native-lib SHARED src/main/jni/native-lib.cpp )#动态方式加载 stringutil-lib是libxxxx.so的xxxx部分add_library(stringutil-lib SHARED IMPORTED)#设置要连接的so的相对路径,${ANDROID_ABI}表示so文件的ABI类型的路径,这一步引入了动态加入编译的soset_target_properties(stringutil-lib  PROPERTIES IMPORTED_LOCATION ${ProjectRoot}/app/libs/jni/${ANDROID_ABI}/libstringutil-lib.so)find_library( log-lib log )#配置加载native依赖#include_directories( ${ProjectRoot}/app/src/main/jni/include )#这里多出了引用的stringutil-libtarget_link_libraries(                       native-lib                       stringutil-lib                       ${log-lib} )

6、测试代码


总结
最为关键的两个步骤
1、在gradlle中指定本地的jni相对路径
2、在CmakeLists.txt中指定加入编译的so及其绝对路径

#动态方式加载 stringutil-lib是libxxxx.so的xxxx部分
add_library(stringutil-lib SHARED IMPORTED)

#设置要连接的so的相对路径,${ANDROID_ABI}表示so文件的ABI类型的路径,这一步引入了动态加入编译的so
set_target_properties(stringutil-lib PROPERTIES IMPORTED_LOCATION ${ProjectRoot}/app/libs/jni/${ANDROID_ABI}/libstringutil-lib.so)

#这里多出了引用的stringutil-lib
target_link_libraries(
native-lib
stringutil-lib
${log-lib} )

由于时间不多,未调试出在CmakeLists.txt 中使用相对路径的办法,我在编译中总是报找不到so的错误。有任何问题欢迎交流。

参考:
http://blog.csdn.net/ddjjll8877/article/details/52670097?
原文:http://blog.csdn.net/mxw3755/article/details/56676923
官方:https://developer.android.com/studio/projects/add-native-code.html#specify-abi
在NDK中可能需要复用之前已经编译好的so文件,所以本章的目标是给一个之前编译好的so文件外加一个需要调用接口的头文件,在现在项目中复用。

在本次实践过程中,已经有编译完成的各种cpu架构的libstringutil-lib.so以及头文件,Stringutil.h
头文件中简单定义了两个接口:
class StringUtil {
public:
static char* toLower(char* chars);
static char* toUpper(char* chars);
};
顾名思义上述接口已在libstringutil-lib.so中实现

现有工程需要调用这些接口,步骤如下:
1、在java层创建native接口
package dev.mars.jnidemo;public class StringUtils {    static {        System.loadLibrary("native-lib");    }    public static native String toLower(String str);    public static native String toUpper(String str);}



2、由Android Studio自动生成native层接口定义,native-lib是实现接口的cpp文件:
extern "C" {JNIEXPORT jstring JNICALLJava_dev_mars_jnidemo_StringUtils_toLower(JNIEnv *env, jclass type, jstring str_) {    const char *str =  env->GetStringUTFChars(str_, 0);    char* str2 =new char[strlen(str)];    strcpy(str2,str);    StringUtil::toLower(str2);    return env->NewStringUTF(str2);}JNIEXPORT jstring JNICALLJava_dev_mars_jnidemo_StringUtils_toUpper(JNIEnv *env, jclass type, jstring str_) {    const char *str =  env->GetStringUTFChars(str_, 0);    char* str2 =new char[strlen(str)];    strcpy(str2,str);    StringUtil::toUpper(str2);    return env->NewStringUTF(str2);}
}


此时编译器应该找不到StringUtil的定义,因此需要将Stringutil.h拷贝到cpp文件所在的文件夹下,本工程中如图所示,新建一个include文件夹,将头文件拷贝过去:
然后在native-lib.cpp中加入头文件的引用:

#include <string>#include <android/log.h>#include "include/StringUtil.h"


3、将所有so文件拷贝到工程的libs/jni目录下

4、修改app下的gradle文件,在android{}中加入如下代码,将so文件作为引用
sourceSets {    main {        jniLibs.srcDirs = ['./libs/jni']    }}

5、下面是最为关键的CmakeLists.txt的配置

cmake_minimum_required(VERSION 3.4.1)#定义变量ProjectRoot为工程根目录,用相对路径没通过编译,可能是路径写错,以后再试#本次使用绝对路径作为参数set(ProjectRoot G:/AndroidStudioProjects/JNIDemo)#将native-lib加入到编译源中add_library( native-lib SHARED src/main/jni/native-lib.cpp )#动态方式加载 stringutil-lib是libxxxx.so的xxxx部分add_library(stringutil-lib SHARED IMPORTED)#设置要连接的so的相对路径,${ANDROID_ABI}表示so文件的ABI类型的路径,这一步引入了动态加入编译的soset_target_properties(stringutil-lib  PROPERTIES IMPORTED_LOCATION ${ProjectRoot}/app/libs/jni/${ANDROID_ABI}/libstringutil-lib.so)find_library( log-lib log )#配置加载native依赖#include_directories( ${ProjectRoot}/app/src/main/jni/include )#这里多出了引用的stringutil-libtarget_link_libraries(                       native-lib                       stringutil-lib                       ${log-lib} )

6、测试代码


总结
最为关键的两个步骤
1、在gradlle中指定本地的jni相对路径
2、在CmakeLists.txt中指定加入编译的so及其绝对路径

#动态方式加载 stringutil-lib是libxxxx.so的xxxx部分
add_library(stringutil-lib SHARED IMPORTED)

#设置要连接的so的相对路径,${ANDROID_ABI}表示so文件的ABI类型的路径,这一步引入了动态加入编译的so
set_target_properties(stringutil-lib PROPERTIES IMPORTED_LOCATION ${ProjectRoot}/app/libs/jni/${ANDROID_ABI}/libstringutil-lib.so)

#这里多出了引用的stringutil-lib
target_link_libraries(
native-lib
stringutil-lib
${log-lib} )

由于时间不多,未调试出在CmakeLists.txt 中使用相对路径的办法,我在编译中总是报找不到so的错误。有任何问题欢迎交流。

参考:
http://blog.csdn.net/ddjjll8877/article/details/52670097?
原创粉丝点击