简体   繁体   English

Android NDK预构建共享库使用

[英]Android NDK prebuild shared library usage

I have precompiled shared library (.so), named libxxx.so.3.3. 我已经预编译了名为libxxx.so.3.3的共享库(.so)。 I don't know why the name after compilation was "libxxx.so.3.3". 我不知道为什么编译后的名称是“ libxxx.so.3.3”。 I'd like to use it in my Android app via JNI. 我想通过JNI在我的Android应用中使用它。 For this i've created ndk module xxx_jni: 为此,我创建了ndk模块xxx_jni:

Android.mk: 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)

I had to rename " .so.3.3" to " .so" as ndk-build failed to compile libxxx_jni.so: 由于ndk-build无法编译libxxx_jni.so,我不得不将“ .so.3.3”重命名为“ .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    

My wrapper class (for JNI): 我的包装器类(对于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;
}

So after ndk compilation (ndk-build) i have 2 stripped files in "libs/armeabi" folder: libxxx.so and libxxx_jni.so. 因此,在ndk编译(ndk-build)之后,我在“ libs / armeabi”文件夹中有2个剥离的文件:libxxx.so和libxxx_jni.so。

Then i try to load libraries in runtime in wrapper class: 然后我尝试在运行时在包装器类中加载库:

public class xxx_wrapper {

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

error: 错误:

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 i'm in stuck what i've missed.. I've tried to leave ".so.3.3" extension and symlink ".so" -> ".so.3.3" but the same result. 所以我陷入了我错过的事情。.我试图保留“ .so.3.3”扩展名和符号链接“ .so”->“ .so.3.3”,但是结果相同。 As far as i understand the problem is that xxx_wrapper lib still wants ".so.3.3" library loaded, but it's ".so". 据我了解,问题在于xxx_wrapper lib仍然希望加载“ .so.3.3”库,但它是“ .so”。

Is it possible the precompiled library wasn't caompiled using ndk-build ? 有可能没有使用ndk-build来预编译预编译的库吗? The Android package manager (and builder!) cannot deal with .so files which have a version number as suffix. Android软件包管理器(和构建器!)无法处理版本号为后缀的.so文件。

You can overcome this by either: 您可以通过以下任一方法克服此问题:

Recompile the library using ndk-build (it would imply writing a new makefile) if you have the sources. 如果有源代码,请使用ndk-build重新编译该库(这意味着编写新的makefile)。

Or: 要么:

Embed the library as an asset in the .apk file. 将库作为资源嵌入到.apk文件中。 When the app starts, save these assets into the applications data folder. 应用启动时,将这些资产保存到应用数据文件夹中。 Now you can use 现在您可以使用

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

which shouldn't fail as it points to a file using a system path, rather than a library that is embedded within the app. 这应该不会失败,因为它指向使用系统路径的文件,而不是指向应用程序内嵌的库。 It means the application will consume more storage on the device, but if you can't recompile the library (and no one else knows a proper solution!) this might be a workaround. 这意味着应用程序将占用设备更多的存储空间,但是如果您无法重新编译该库(并且没有人知道合适的解决方案!),这可能是一种解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM