> 文章列表 > 编译和引用so库

编译和引用so库

编译和引用so库

编译和引用so库

1.两种编译方式

  • ndk-build + Android.mk + Application.mk
  • CMake + CMakeList

2.Android.mk + Application.mk

(1)javac java文件的绝对路径 → 生成so库

(2)javah com.xxx.xxx.tesAdd → 生成头文件

(3) 修改头文件的后缀,并添加实现

(4)Application.mk

APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
APP_MODULES := testAdd
APP_CFLAGS += -DSTDC_HEADERS
APP_PLATFORM := android-21

(5)Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)LOCAL_C_INCLUDES := $(LOCAL_PATH)		#头文件的路径LOCAL_MODULE := testAddLOCAL_SRC_FILES := Num.cpp\\com_android_makeso_2_testAdd.cppLOCAL_LDLIBS := -L$(SYSROOT)/usr/lib-llog
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true			#不加头文件会有.o文件中的汇编问题
include $(BUILD_SHARED_LIBRARY)

(6) 编库

在当前目录运行 ndk-build

目前编这个库会有使用的问题

	AndroidRuntime: FATAL EXCEPTION: mainProcess: com.android.makeso_2, PID: 17911java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSt6__ndk14coutE" referenced by "/data/app/~~zMsVpovir-8ZGyyQC6QYQQ==/com.android.makeso_2-tC41E73EDKkgmsQ4flEfpw==/base.apk!/lib/arm64-v8a/libtestAdd.so"

根据查询,应该是mk文件的编译问题

和c++_static库有些关系

3.CMake + CMakeList

(1) java文件载入

public class testAdd {static {System.loadLibrary("testAdd");}testAdd() {init();}public native int add(int a,int b);public native int min(int a,int b);public native int init();public native int destory();
}

(2) 生成jni方法

JNIEXPORT jint JNICALL Java_com_android_makeso_12_testAdd_min(JNIEnv *, jobject, jint, jint);

注意return!!

(3) CMakeList.txt

add_library( # Sets the name of the library.application_makeso# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).native-lib.cppNum.cpp)

在build/intermediate/cmake 库找到编译出来的so库

4.so文件的使用

  • 编写java文件
    • 加载库
    • 写native方法(so库中的实现方法需要注意函数名)
  • 把so库放到jniLib(默认加载)
No implementation found for int com.android.useso.testAdd.init() (tried Java_com_android_useso_testAdd_init and Java_com_android_useso_testAdd_init__)