Android NDK - 链接共享库和 JNI 包装器时出错
Android NDK - Error Linking Shared library and JNI Wrapper
我正在尝试 link 我在另一台构建机器上使用 NDK 独立工具链生成的共享库。然后使用那个特定的 .so
我把它放在 Android Studio 上。从那里我使用 javah 创建了一个 jni.h
文件,然后帮助我为函数调用编写了 .c
JNI。
按照这个例子How do I compile any native (C, C++) library using NDK in the form of shared libraries .
ndk-build
确实编译并且似乎工作正常但是当尝试 运行 phone 上的应用程序时我在
处收到错误
static {
System.loadLibrary("testLib")
}
说找不到 testLib.so
即使它已生成并且在 libs/armeabi-v7a/testLib.so
目录中
当前错误:
01-31 14:41:53.779 19024-19024/com.jolopy.testing_02 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.jolopy.testing_02, PID: 19024
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.jolopy.testing_02-2/base.apk"],nativeLibraryDirectories=[/data/app/com.jolopy.testing_02-2/lib/arm64, /vendor/lib64, /system/lib64]]] couldn't find "testLib.so"
at java.lang.Runtime.loadLibrary(Runtime.java:367)
at java.lang.System.loadLibrary(System.java:1076)
at com.jolopy.testing_02.TestLib.<clinit>(TestLib.java:6)
at com.jolopy.testing_02.MainActivity.onCreate(MainActivity.java:18)
我如何构建 .so
文件:
arm-linux-androideabi-gcc -c -fPIC testLib.c -o test.o
arm-linux-androideabi-gcc test.o -o testing.so
从那里我使用 javah
编写了一个 JNI 包装器 class,它生成了 testing_Android.h
文件。从那里生成了 testing_Android.c JNI 包装器,我用它来调用我的 testLib.c
库中的函数:
#include "testLib.h"
//Including Machine Generated Header
#include "testing_Android.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_com_jolopy_testing_102_TestLib_testinglib_1Initialize
(JNIEnv *env, jobject obj){
(void)env;
(void)obj;
testing_Initialize();
}
JNIEXPORT jint JNICALL Java_com_jolopy_testing_102_TestLib_testinglib_1Get_1Count
(JNIEnv *env, jobject obj){
(void)env;
(void)obj;
return(testing_Get_Count());
}
JNIEXPORT jint JNICALL Java_com_jolopy_testing_102_TestLib_testinglib_1Get_1CurrentName
(JNIEnv *env, jobject obj, jlong ptr, jint x){
(void)env;
(void)obj;
return (testing_Get_CurrentName((char *)ptr , (int)x));
}
从那里我在 Android 的 jni 文件夹中有 5 个文件,这是我 运行 来自的 ndk-build 命令的位置:
testing.so | testing_Android.h | testing_Android.c | Application.mk | Android.mk
Android.mk:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := testLib
LOCAL_SRC_FILES := testing.so
LOCAL_EXPORT_C_INCLUDES := testing_Android.c
include $(PREBUILT_SHARED_LIBRARY)
Application.mk:
APP_PLATFORM := android-19
APP_ABI := armeabi-v7a
如果您在我的进度中看到我没有提出的任何建议或错误,我们将不胜感激。
-干杯!
以下更改
APP_ABI := armeabi-v7a
到
APP_ABI := arm64-v8a
因为从你的错误日志来看,你的设备是 arm64 ABI。
如果您正在开始一个新的 Android NDK 项目,我建议您从 Android Studio + CMake 工具链开始,请参阅此处对于我基于 Android Studio 和 CMake 的个人 JniExample 项目:
我没有使用 ndk 独立工具链,而是在我的构建机器上使用了 ndk-build,它随后生成了我需要的 libs 文件。从那里我添加了包含以下内容的 libs 文件:
- arm64-v8a
- armeabi-v7a
- x86
- x86_64
进入 src>main>jniLibs 下我的 Android 目录,然后存储所有文件并将命令添加到我的应用程序 build.gradle:
sourceSets.main{
jniLibs.srcDir 'src/main/jniLibs'
}
为了让 ndk-build 正常工作,我必须包含 jniWrapper.c 文件。
Android.mk:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := testing
LOCAL_SRC_FILES := jniWrapper.c \
testLib.c
include $(BUILD_SHARED_LIBRARY)
Application.mk(我正在使用 "all" 进行测试,但不需要):
APP_PLATFORM := android-23
APP_ABI := all
我知道这是一个变通解决方案,但出于某种原因,我无法弄清楚工具链能否正常工作。
我正在尝试 link 我在另一台构建机器上使用 NDK 独立工具链生成的共享库。然后使用那个特定的 .so
我把它放在 Android Studio 上。从那里我使用 javah 创建了一个 jni.h
文件,然后帮助我为函数调用编写了 .c
JNI。
按照这个例子How do I compile any native (C, C++) library using NDK in the form of shared libraries .
ndk-build
确实编译并且似乎工作正常但是当尝试 运行 phone 上的应用程序时我在
static {
System.loadLibrary("testLib")
}
说找不到 testLib.so
即使它已生成并且在 libs/armeabi-v7a/testLib.so
目录中
当前错误:
01-31 14:41:53.779 19024-19024/com.jolopy.testing_02 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.jolopy.testing_02, PID: 19024
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.jolopy.testing_02-2/base.apk"],nativeLibraryDirectories=[/data/app/com.jolopy.testing_02-2/lib/arm64, /vendor/lib64, /system/lib64]]] couldn't find "testLib.so"
at java.lang.Runtime.loadLibrary(Runtime.java:367)
at java.lang.System.loadLibrary(System.java:1076)
at com.jolopy.testing_02.TestLib.<clinit>(TestLib.java:6)
at com.jolopy.testing_02.MainActivity.onCreate(MainActivity.java:18)
我如何构建 .so
文件:
arm-linux-androideabi-gcc -c -fPIC testLib.c -o test.o
arm-linux-androideabi-gcc test.o -o testing.so
从那里我使用 javah
编写了一个 JNI 包装器 class,它生成了 testing_Android.h
文件。从那里生成了 testing_Android.c JNI 包装器,我用它来调用我的 testLib.c
库中的函数:
#include "testLib.h"
//Including Machine Generated Header
#include "testing_Android.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_com_jolopy_testing_102_TestLib_testinglib_1Initialize
(JNIEnv *env, jobject obj){
(void)env;
(void)obj;
testing_Initialize();
}
JNIEXPORT jint JNICALL Java_com_jolopy_testing_102_TestLib_testinglib_1Get_1Count
(JNIEnv *env, jobject obj){
(void)env;
(void)obj;
return(testing_Get_Count());
}
JNIEXPORT jint JNICALL Java_com_jolopy_testing_102_TestLib_testinglib_1Get_1CurrentName
(JNIEnv *env, jobject obj, jlong ptr, jint x){
(void)env;
(void)obj;
return (testing_Get_CurrentName((char *)ptr , (int)x));
}
从那里我在 Android 的 jni 文件夹中有 5 个文件,这是我 运行 来自的 ndk-build 命令的位置:
testing.so | testing_Android.h | testing_Android.c | Application.mk | Android.mk
Android.mk:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := testLib
LOCAL_SRC_FILES := testing.so
LOCAL_EXPORT_C_INCLUDES := testing_Android.c
include $(PREBUILT_SHARED_LIBRARY)
Application.mk:
APP_PLATFORM := android-19
APP_ABI := armeabi-v7a
如果您在我的进度中看到我没有提出的任何建议或错误,我们将不胜感激。
-干杯!
以下更改
APP_ABI := armeabi-v7a
到
APP_ABI := arm64-v8a
因为从你的错误日志来看,你的设备是 arm64 ABI。
如果您正在开始一个新的 Android NDK 项目,我建议您从 Android Studio + CMake 工具链开始,请参阅此处对于我基于 Android Studio 和 CMake 的个人 JniExample 项目:
我没有使用 ndk 独立工具链,而是在我的构建机器上使用了 ndk-build,它随后生成了我需要的 libs 文件。从那里我添加了包含以下内容的 libs 文件:
- arm64-v8a
- armeabi-v7a
- x86
- x86_64
进入 src>main>jniLibs 下我的 Android 目录,然后存储所有文件并将命令添加到我的应用程序 build.gradle:
sourceSets.main{
jniLibs.srcDir 'src/main/jniLibs'
}
为了让 ndk-build 正常工作,我必须包含 jniWrapper.c 文件。
Android.mk:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := testing
LOCAL_SRC_FILES := jniWrapper.c \
testLib.c
include $(BUILD_SHARED_LIBRARY)
Application.mk(我正在使用 "all" 进行测试,但不需要):
APP_PLATFORM := android-23
APP_ABI := all
我知道这是一个变通解决方案,但出于某种原因,我无法弄清楚工具链能否正常工作。