【问题标题】:Android NDK prebuild shared library usageAndroid NDK prebuild 共享库使用
【发布时间】:2013-10-03 13:24:15
【问题描述】:

我已经预编译了共享库 (.so),名为 libxxx.so.3.3。不知道为什么编译后的名字是“libxxx.so.3.3”。我想通过 JNI 在我的 Android 应用程序中使用它。为此,我创建了 ndk 模块 xxx_jni:

Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := xxx
LOCAL_SRC_FILES := xxx.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := xxx_jni
LOCAL_SRC_FILES := xxx_wrapper.c
LOCAL_SHARED_LIBRARIES := xxx
LOCAL_C_INCLUDES := /softdev/xxx/host/include/

include $(BUILD_SHARED_LIBRARY)

我不得不将“.so.3.3”重命名为“.so”,因为 ndk-build 无法编译 libxxx_jni.so:

Android NDK: ERROR:/Users/user/Documents/dev/src/xxx_jni/jni/Android.xxx: LOCAL_SRC_FILES should point to a file ending with ".so"    
Android NDK: The following file is unsupported: libxxx.so.3.3    

我的包装类(用于 JNI):

#include "xxx_wrapper.h"
#include <xxx-c/Index.h> // include "xxx" library header

#ifndef _Included_name_antonsmirnov_android_xxx_wrapper
#define _Included_name_antonsmirnov_android_xxx_wrapper
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     name_antonsmirnov_android_xxx_wrapper
 * Method:    exec_test
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_name_antonsmirnov_android_xxx_1wrapper_exec_1test(JNIEnv *, jobject, jstring)
{
    // using method from "xxx" library
    xxx_method();

    return 7;
}

所以在 ndk 编译(ndk-build)之后,我在“libs/armeabi”文件夹中有 2 个剥离文件:libxxx.so 和 libxxx_jni.so。

然后我尝试在包装类中加载运行时库:

public class xxx_wrapper {

    static {
        System.loadLibrary("xxx");
        System.loadLibrary("xxx_jni"); // error here!
    }

错误:

at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1891]:   167 could not load needed library 'libxxx.so.3.3' for 'libxxx_jni.so' (load_library[1093]: Library 'libxxx.so.3.3' not found)

所以我卡住了我错过的东西。我试图留下“.so.3.3”扩展名和符号链接“.so”->“.so.3.3”但结果相同。据我了解,问题是 xxx_wrapper lib 仍然希望加载“.so.3.3”库,但它是“.so”。

【问题讨论】:

    标签: android android-ndk shared-libraries


    【解决方案1】:

    预编译的库是否可能没有使用 ndk-build 编译? Android 包管理器(和构建器!)无法处理以版本号为后缀的 .so 文件。

    您可以通过以下任一方式克服此问题:

    如果您有源代码,请使用 ndk-build 重新编译库(这意味着要编写一个新的 makefile)。

    或者:

    将库作为资产嵌入到 .apk 文件中。当应用程序启动时,将这些资产保存到应用程序数据文件夹中。现在你可以使用

    System.load( "/path/to/lib/libxxx.so.3.3" );
    

    它不应该失败,因为它使用系统路径指向文件,而不是嵌入在应用程序中的库。这意味着应用程序将在设备上消耗更多存储空间,但如果您无法重新编译库(并且没有其他人知道正确解决方案!),这可能是一种解决方法。

    【讨论】:

    • AFAIK loadLibrary 不采用“.so.3.3”并加载库“libxxx.so”,您应该编写不带任何后缀和前缀的 loadLibrary("xxx")。你确定它有效吗? PS。我可以重命名“armeabi”文件夹中的文件..
    • 它适用于 System.load("%full_path_with_suffix%")。谢谢!
    • 我仍然收到UnsatisfiedLinkError: Cannot load library: load_library
    猜你喜欢
    • 1970-01-01
    • 2018-02-20
    • 2015-03-27
    • 1970-01-01
    • 2011-07-15
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多