我有预编译的共享库(.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” - &gt; “.so.3.3”但结果相同。据我所知,问题是xxx_wrapper lib仍然需要加载“.so.3.3”库,但它是“.so”。
答案 0 :(得分:1)
是否可以使用ndk-build对预编译库进行编译? Android包管理器(和构建器!)无法处理版本号为后缀的.so文件。
您可以通过以下方式解决此问题:
如果你有源代码,可以使用ndk-build重新编译库(这意味着要编写一个新的makefile)。
或者:
将库作为资源嵌入.apk文件中。应用程序启动时,将这些资产保存到应用程序数据文件夹中。现在你可以使用
System.load( "/path/to/lib/libxxx.so.3.3" );
它不应该失败,因为它指向使用系统路径的文件,而不是嵌入在应用程序中的库。这意味着应用程序将在设备上消耗更多存储空间,但如果您无法重新编译库(并且没有其他人知道正确的解决方案!),这可能是一种解决方法。