【问题标题】:NDK - How to use a generated .so library in another projectNDK - 如何在另一个项目中使用生成的 .so 库
【发布时间】:2011-08-05 20:50:30
【问题描述】:

我已成功使用 ndk 在一个项目中构建和使用 .so 文件。我需要在另一个项目中使用这个库。我宁愿不在那里复制源代码,而只是使用库。

尝试将整个libs/armeabi/libcommon.so 复制并粘贴到项目根目录不起作用,我认为是因为libs/armeabi 是android 生成的路径。

那么最好的方法是什么?

我正在使用 Eclipse-Galileo 和 ndk5。

【问题讨论】:

    标签: android android-ndk java-native-interface


    【解决方案1】:

    有一种更简单的方法可以完成所有这些操作。

    假设您的预构建库名为“libprebuilt.so”

    在您只想包含预建库的新项目的项目文件夹中,执行以下操作:

    mkdir -p jni/libprebuilt
    cp libprebuilt.so jni/libprebuilt
    

    然后,只需创建一个 jni/libprebuilt/Android.mk 文件:

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := libprebuilt
    LOCAL_SRC_FILES := libprebuilt.so
    include $(PREBUILT_SHARED_LIBRARY)
    

    然后当你进行 ndk-build 时,它会将这个库复制到 libs/armeabi/ ... 就是这样!

    【讨论】:

    • +1 。谢谢。我重新审视了这个问题并看到了你的答案。在这种情况下,您将如何包含 .h 文件?我的意思是 ProjectA 中的 src 文件包括来自 ProjectB 的 .h 文件。当我使用你的方法时,ndk-build 找不到它们。
    • @OceanBlue:只需将其放入 jni/ 而不是 jni/libprebuilt。通常,您可以将所有 .so .a 文件复制到新项目中,保持相同的层次结构,/libs/armeabi 和 /obj/local/armeabi。实际上,上面的 android.mk 只是做了同样的复制。
    • 没有人使用共享库有问题吗?我的 Android.mk 在调试中与共享库一起工作得很好,但在发布时复制它们的信息较少(预建文件夹中的原始版本)并且不起作用。
    • 嗨,@gnychis。作为 Komi 的回答,我看到 OceanBlue 的回答是正确的,但它很复杂。关于您的解决方案,您能否解释一下您的解决方案中的“Java_com_myapp_myclass_funct”?
    • @gnychis 我遇到了同样的问题我已经尝试过你的解决方案,但它不能解决我的问题保存问题本地方法未找到错误。我已将 .so 文件放在 armeabi-v7a 下的 JniLibs 文件夹中x86
    【解决方案2】:

    我想出了一个办法,所以把它贴在这里以防其他人遇到它。

    1. 要共享的代码(包括 Java JNI 包装器、本机代码、.so 库)应位于单独的项目中。通过右键单击项目名称-> 属性-> Android 属性-> 选中“是库”将其转换为库项目。该项目现在无法执行,但可以被其他项目引用。

    2. 在将使用共享对象的项目中,通过右键单击项目名称--> 属性--> Android 属性--> 库/“添加”来添加对 Libarray 项目的引用。这应该会显示在上一步中创建的库项目。选择它。

    现在.so 可以在不同项目之间轻松引用。

    【讨论】:

    • 不要忘记使用 Java 代码包装对本机的所有调用,否则您将不得不重新编译所有项目的方法名称。我通常将它们放在一个或几个不同的类中,然后调用这些类。
    【解决方案3】:

    在所有 JNI(Java 本地接口)函数名称中都有一个包名称(例如 JNIEXPORT void JNICALL Java_com_myapp_myclass_funct)。所以我想你应该在库中重命名这些 funkcions 并重新编译它。或者也许将它用作您的应用程序中的外部包。

    【讨论】:

    • 谢谢,我忘记了 package_name_in_jni_method_names。当然,那是行不通的。您能否详细说明您的第二个建议...将其用作外部包...如果我尝试“导入”选项,它不会让我导入 .so 类型,只能导入 JAR 等。
    • 我不确定,但您不能在当前项目中创建另一个具有您需要的名称的包吗?只是猜测,从未尝试过..
    • @Komi,是的。简单的选项是根据 jni 命名约定重命名库中的函数,然后将 .so 文件复制到适当的位置。这将避免导入为外部包及其附带的所有内容。
    猜你喜欢
    • 2016-09-19
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 2011-08-03
    相关资源
    最近更新 更多