我在 Android 上有一个 libjpeg-turbo 的 JNI 实现。
应用程序构建没有任何问题,我可以在生成的 APK 文件中看到 native libJPEGProcessing.so
库位于不同架构的 lib
文件夹中。
但是,当通过应用程序调用 native 方法时,我将收到以下“未找到实现”消息,这将导致异常:
D/dalvikvm: No JNI_OnLoad found in /system/lib/libjpeg.so 0xa4fe3dc0, skipping init
D/dalvikvm: Trying to load lib /data/app-lib/com.google.test-2/libJPEGProcessing.so 0xa4fe3dc0
D/dalvikvm: Added shared lib /data/app-lib/com.google.test-2/libJPEGProcessing.so 0xa4fe3dc0
D/dalvikvm: No JNI_OnLoad found in /data/app-lib/com.google.test-2/libJPEGProcessing.so 0xa4fe3dc0, skipping init
W/dalvikvm: No implementation found for native Lcom/google/test/NativeMethods;.computeUsableDCTCoefficientsLinkedList:(Ljava/lang/String;)I
这是我在 JNI 中的方法:
extern "C" {
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
// Get jclass with env->FindClass.
// Register methods with env->RegisterNatives.
return JNI_VERSION_1_6;
}
JNIEXPORT jint JNICALL Java_com_google_test_NativeMethods_computeUsableDCTCoefficientsLinkedList
(JNIEnv *env, jobject obj, jstring javaString)
{
...
}
}
以及生成的头文件:
extern "C" {
/*
* Class: com_google_test_NativeMethods
* Method: computeUsableDCTCoefficientsLinkedList
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_google_test_NativeMethods_computeUsableDCTCoefficientsLinkedList
(JNIEnv *, jclass, jstring);
}
Java 中的实现如下所示:
package com.google.test;
import java.util.ArrayList;
public class NativeMethods {
private String filename = null;
private int fromNative = -100;
private int numberInList = -100;
private ArrayList<DCTCoefficient> array = null;
static {
System.loadLibrary("jpeg");
System.loadLibrary("JPEGProcessing");
}
public static native int computeUsableDCTCoefficientsLinkedList(String filename);
}
这是用于 ndk-build
的 Android.mk
:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_FILES := ./libjpeg-turbo/
LOCAL_MODULE := JPEGProcessing
LOCAL_CFLAGS := -Ic:\AndroidStudioProjects\Test\Test\src\main\jni\ -Ic:\libjpeg-turbo-gcc\include\
LOCAL_SRC_FILES := JPEGProcessing.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_STATIC_LIBRARIES := c:\libjpeg-turbo-gcc\lib\libjpeg.a
include $(BUILD_SHARED_LIBRARY)
在构建和编译过程中没有错误,应用程序将在 Android 设备上正常启动。但是,我定义了 JNI_OnLoad 方法,在 Java 类中加载 native 库后也不会调用该方法。
编辑:
我在 Gradle Console 中发现了以下可能与之相关的警告:
Android NDK: WARNING:C:/AndroidStudioProjects/Test/Test/src/main/jni/Android.mk:JPEGProcessing: non-system libraries in linker flags: c:\libjpeg-turbo-gcc\lib\libjpeg.a
Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module
编辑 2:
尝试在 Linux 上查看已编译的 libJPEGProcessing.so 内部:
nm libJPEGProcessing.so
nm: libJPEGProcessing.so: no symbols
nm -D libJPEGProcessing.so
00002004 A __bss_start
U __cxa_atexit
U __cxa_finalize
00002004 A _edata
00002004 A _end
没有导出的 JNI 方法和符号。这是正确的吗?
编辑 3:
ndk-build.cmd -B V=1 APP_ABI=armeabi
的输出:
ndk-build.cmd -B V=1 APP_ABI=armeabi
del /f/q c:\AndroidStudioProjects\Test\Test\src\main\libs\arm64-v8a\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\armeabi\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\armeabi-v7a\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\mips\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\mips64\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\x86\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\x86_64\libJPEGProcessing.so >NUL 2>NUL
[armeabi] SharedLibrary : libJPEGProcessing.so
C:/Android/sdk/ndk-bundle/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libJPEGProcessing.so -shared --sysroot=C:/Android/sdk/ndk-bundle/build//../platforms/android-9/arch-arm -lgcc -gcc-toolchain C:/Android/sdk/ndk-bundle/build//../toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 -no-canonical-prefixes -target armv5te-none-linux-androideabi -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -lc -lm -o c:/AndroidStudioProjects/Test/Test/src/main/obj/local/armeabi/libJPEGProcessing.so
[armeabi] Install : libJPEGProcessing.so => libs/armeabi/libJPEGProcessing.so
copy /b/y "c:\AndroidStudioProjects\Test\Test\src\main\obj\local\armeabi\libJPEGProcessing.so" "c:\AndroidStudioProjects\Test\Test\src\main\libs\armeabi\libJPEGProcessing.so" > NUL
最佳答案
您的代码似乎没问题 - 我看不到任何签名问题,而且您似乎正在以所需的方式加载库。但是,事实是日志说找到了库,但它找不到您的 JNI_OnLoad 实现。您是否有可能拥有多个版本的 libJPEGProcessing.so,并且系统会找到一个较旧的版本?当然,我不是在谈论针对不同架构的不同库。
关于java - Android JNI NDK - 未找到实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42460857/