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

时间:2013-07-16 22:53:56

标签: android build android-ndk java-native-interface shared-libraries

浪费了半天时间尝试构建两个共享库,例如从{j}文件夹和子文件夹中的来源mod1mod2(Android NDK编译为libmod1.solibmod2.so),然后让mod1从mod2调用函数。关于如何使构建工作的大量答案,但随后运行时动态链接无效,应用程序在启动时崩溃。

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

1 个答案:

答案 0 :(得分:24)

正确的构建过程相对容易,我的问题是使libmod1.so依赖于libmod2.so在启动时导致不满意的链接 - mod1代码找不到mod2共享库,即使两者都存在于同一个文件夹中最终的APK,在libs / armeabi下,libs / x86等。但是,为了让我的答案完整:

  • 将您的C或C ++源代码和头文件放在Android项目的jni目录的子目录下,例如:文件夹mod1 /和mod2 /

  • 根据NDK指令,创建Application.mk文件,例如:我的是:

  

NDK_TOOLCHAIN_VERSION = 4.7
  APP_PLATFORM:= android-8
  APP_ABI:= armeabi armeabi-v7a x86

  • 按照以下模板创建Android.mk:
  

LOCAL_PATH:= $(致电my-dir)
  包括$(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
  ...
  include $(BUILD_SHARED_LIBRARY)#这实际上构建了libmod1.so
  
  包括$(CLEAR_VARS)
  LOCAL_MODULE:= mod2
  LOCAL_SRC_FILES:= mod2 / file1.cc
  LOCAL_SRC_FILES + = mod2 / file2.cc
  ...
  include $(BUILD_SHARED_LIBRARY)#this build libmod2.so

就是这样,所有构建都没有抱怨ndkbuild脚本。您只需要一个C包装器来从Java调用某些函数。这是我的问题。因为我只能在libmod1.so中使用Java调用函数,所以Java中的C包装类就像:

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,对吧?错误!它在app启动时崩溃了“不满意的链接”。确切的错误消息是:

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来解决这个问题是徒劳的。终于尤里卡!我按如下方式修改了我的CWrapper类:

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);
    ...
}

并且事情开始像魅力......

格雷格