首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Android NDK -使两个本机共享库相互调用

Android NDK -使两个本机共享库相互调用
EN

Stack Overflow用户
提问于 2013-07-17 06:53:56
回答 1查看 8.6K关注 0票数 21

我花了半天的时间尝试从jni文件夹和子文件夹中的源代码构建两个共享库,例如mod1mod2 ( Android NDK将其编译为libmod1.solibmod2.so),然后让mod1调用mod2中的函数。有很多关于如何使构建工作的答案,但随后运行时动态链接不起作用,应用程序在启动时崩溃。

我决定发布这个问题并立即回答它,这样整个过程中的Q和A就可以在一起了,希望其他人不会再浪费一天的时间来研究它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-17 07:22:30

正确的构建过程相对简单,我的问题是使libmod1.so依赖于libmod2.so在启动时导致不满意的链接- mod1代码无法找到mod2共享库,即使两者都存在于最终APK中的同一文件夹中,位于libs/armeabi、libs/x86等下。

  • 将你的C或C++源代码和头文件放在你的安卓项目的jni目录子目录下,例如mod1/和mod2/
  • 文件夹,按照NDK的说明创建Application.mk文件,例如我的是:

NDK_TOOLCHAIN_VERSION=4.7

APP_PLATFORM :=安卓-8

APP_ABI := armeabi armeabi-v7a x86

  • 遵循以下模板创建Android.mk:

LOCAL_PATH目录$(调用my- := )

包含$(CLEAR_VARS)

LOCAL_SHARED_LIBRARIES := mod2   #这使得libmod1.so依赖于libmod2.so

LOCAL_MODULE := mod1

LOCAL_SRC_FILES := mod1/file1.c

LOCAL_SRC_FILES += mod1/file2.cpp

..。

包含$(BUILD_SHARED_LIBRARY)   #这实际上构建了libmod1.so包含$(CLEAR_VARS)

LOCAL_MODULE := mod2

LOCAL_SRC_FILES := mod2/file1.cc

LOCAL_SRC_FILES += mod2/file2.cc

..。

包含$(BUILD_SHARED_LIBRARY)   #这将构建libmod2.so

就是这样,所有的构建都使用了ndkbuild脚本。您只需要一个C包装器来调用Java中的一些函数。这就是我的问题。由于我只有在libmod1.so中才有可从Java调用的函数,所以我的Java C包装器类如下所示:

代码语言:javascript
复制
public class CWrapper {
    static {
        System.loadLibrary("mod1");
    }
    public static native int func1(String aParam);
    ...
}

这对我来说似乎是非常合乎逻辑的-我从Java调用libmod1.so,所以我使用了System.loadLibrary("mod1"),既然libmod1.so知道它依赖于libmod2.so,而且两个文件都在同一个文件夹中,libmod1应该知道如何查找和加载libmod2,对吧?不对!它在应用程序启动时崩溃,并带有“不满意的链接”。确切的错误消息是:

代码语言:javascript
复制
java.lang.UnsatisfiedLinkError: Cannot load library: soinfo_link_image(linker.cpp:1635): could not load library "libmod2.so" needed by "libmod1.so"; caused by load_library(linker.cpp:745): library "libmod2.so" not found

我到处寻找更多的代码来添加到Android.mk中,以解决这个问题,但没有成功。终于有了Eureka!我修改了CWrapper类,如下所示:

代码语言:javascript
复制
public class CWrapper {
    static {
        System.loadLibrary("mod2"); // must be first, as mod1 depends on mod2!
        System.loadLibrary("mod1");
    }
    public static native int func1(String aParam);
    ...
}

事情开始变得像魔咒一样有效。

格雷格

票数 26
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17688327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档