java - Android JNI NDK - 未找到实现

标签 java android c++ android-ndk java-native-interface

我在 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-buildAndroid.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/

相关文章:

android - 为 Material Design 设计 Android Lollipop 中的 SwitchCompat 按钮样式/着色

java - 如何在java android中对数字进行排序?

java - 如何在 Android 上演奏非正弦音符?迷笛?

java - 使用 java 客户端 api 对 Marklogic 数据库中的文档进行批量修补

java - 注销 Facebook Android SDK

c++ - 两个数字相加时出错(链表中的数字)

c++ - UNIX API 调用 : Using read() function to open and print a file to the screen adds extra random characters

java - 对象创建(状态初始化)和线程安全

android - ShowcaseView 的叠加层不透明

c++ - 在 macOS 10.13.6 clang 7.0 上的 Qt 5.12.0 上找不到“QtSerialPort”文件