APK里面有两个共享对象

时间:2013-01-03 11:11:57

标签: android c android-ndk dlopen shared-libraries

根据docs / PREBUILTS.html,允许在NDK应用程序中使用预构建的共享对象。所以我试着让我的NDK应用程序从第二个共享对象导入一个函数,但是一旦我在我的APK中使用第二个共享对象,整个shebang甚至在输入android_main()之前就崩溃了。 LogCat说:

E/AndroidRuntime( 1931):
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.TEST/android.app.NativeActivity}:
java.lang.IllegalArgumentException: Unable to load native library: /data/data/com.example.TEST/lib/libTEST.so

为了追踪这一点,我设置了以下简约测试用例:

int addvals(int a, int b) { return a + b; }

现在只使用包含此函数的源编译为共享对象 这些构建文件:

# Application.mk
APP_MODULES := sharedobjecttest
APP_ABI := armeabi-v7a armeabi
APP_PLATFORM := android-9

# Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE     := sharedobjecttest
LOCAL_SRC_FILES  := addvals.c
include $(BUILD_SHARED_LIBRARY)

现在我想从我的主共享对象中调用addvals()函数。代码 又一次简约了:

#include <stdlib.h>
#include <android/log.h>
#include <android_native_app_glue.h>

// prototype for function imported from libsharedobjecttest.so
int addvals(int a, int b);

void android_main(struct android_app* state) {
    app_dummy();   // Make sure glue isn't stripped
    __android_log_print(ANDROID_LOG_INFO, "LogTag", "Hello World!\n"); 
    __android_log_print(ANDROID_LOG_INFO, "LogTag", "5+6=%d\n", addvals(5, 6)); 
    exit(0);
}

主要共享对象的构建文件如下所示:

# Application.mk
APP_ABI := armeabi-v7a armeabi
APP_PLATFORM := android-9

# Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libsharedobjecttest
LOCAL_SRC_FILES := ../../SharedObjectTest/libs/$(TARGET_ARCH_ABI)/libsharedobjecttest.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE     := TEST
LOCAL_SRC_FILES  := main.c
LOCAL_LDLIBS     := -llog -landroid
LOCAL_SHARED_LIBRARIES := sharedobjecttest android_native_app_glue
include $(BUILD_SHARED_LIBRARY)

$(call import-module,android/native_app_glue)

最终的共享对象(libTEST.so)链接得很好。对addvals的外部依赖() 已解决,并放置了两个共享对象(libsharedobjecttest.so和libTEST.so) 进入我最后的APK。 ARM架构也是正确的。

然而,当尝试加载libTEST.so时,APK会立即崩溃。 android_main()不是 甚至进入。当我删除对libsharedobjecttest的引用时,崩溃消失了,APK运行正常。那么有人知道为什么会崩溃吗?

我是否必须使用dlopen()和dlsym()手动解决所有外部依赖项?但是当外部共享对象有很多主要共享对象需要的符号时,这将是很多工作...:/

当然,我可以使用静态库而不是第二个共享对象,但我更喜欢使用共享对象。当docs / PREBUILTS.html明确谈到在项目中使用预构建的共享对象的可能性时,我不认为我在这里做了一些禁止的事情。但问题是:为什么它会崩溃然后如何解决这个问题呢?

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

回答我自己的问题:必须手动为所有必需的共享对象创建NativeActivity类的子类并调用System.loadLibrary()。另一种解决方案是使用dlopen(),但在这种情况下,必须首先找到应用程序的绝对路径,因为dlopen()仅在传递相对共享对象时查找系统文件夹。

相关问题