2013-07-16 45 views
17

浪费了半天的时间试图构建两个共享库,例如mod1mod2(其中Android NDK编译为libmod1.solibmod2.so),来自jni文件夹和子文件夹中的源,然后让mod1从mod2调用一个函数。关于如何使构建工作,但然后运行时动态链接无效的答案很多,应用程序在启动时崩溃。Android NDK - 使两个本地共享库互相调用

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

回答

22

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

  • 把你的C或C++在你的Android项目源和头文件下的JNI目录的子目录,例如文件夹mod1 /和mod2/

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

NDK_TOOLCHAIN_VERSION = 4.7
APP_PLATFORM:= Android的8
APP_ABI:= armeabi armeabi-V7A 86

  • 创建Android.mk下面这个模板:

LOCAL_PATH:= $(叫我-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
...
包括$(BUILD_SHARED_LIBRARY)     #这实际上建立libmod1.so

包括$(CLEAR_VARS)
LOCAL_MODULE:= MOD2
LOCAL_SRC_FILES:= MOD2/file1.cc
LOCAL_SRC_FILES + =模2/file2.cc
...
包括$(BUILD_SHARED_LIBRARY)     #此建立libmod2 .so

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

public class CWrapper { 
    static { 
     System.loadLibrary("mod1"); 
    } 
    public static native int func1(String aParam); 
    ... 
} 

这似乎完全合乎逻辑的,我 - 我称之为从Java到libmod1.so,所以我用的System.loadLibrary(“MOD1”),并自libmod1。所以知道它取决于libmod2.so,并且这两个文件都在同一个文件夹中,libmod1将知道如何查找并加载libmod2,对不对?错误!它在应用程序启动时以“不满意的链接”崩溃。确切的错误信息是:

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

,事情开始像一个魅力的工作...

格雷格

+1

由此我们可以得出结论,该系统的动态加载程序并加载依赖(标准行为),而Java加载程序则不行。 – Samveen

+0

这是一个很好的观察,@Samveen。也许我应该在新版本的Android下重新测试,看看他们最近是否有改进。 – gregko

相关问题