【问题标题】:Embed C library in Java library在 Java 库中嵌入 C 库
【发布时间】:2020-10-04 18:32:13
【问题描述】:

我有一个用于 Android 的 Java 库,我分发给第三方开发人员,我想在其中嵌入一个 C 库。我已通过 CMake 将库添加到项目中:

add_library(wrapper SHARED wrap.c)
target_link_libraries(wrapper CLibraryTarget)

我已添加到库的 build.gradle 中:

apply plugin: 'com.android.library'

...

android {
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                cppFlags ""
                targets "wrapper",
                "CLibraryTarget"
            }
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.0+"
        }
    }
}

在库中,我加载 C 库:

public class Wrapper {
  static {
    System.loadLibrary("wrapper");
  }
  ...
}

我正在尝试运行单元测试来测试一些包装 C 函数的 Java 函数,但我得到了异常:

java.lang.UnsatisfiedLinkError: no wrapper in java.library.path

    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1871)
...

这在我在应用程序中链接 C 库时有效,但在 Java 库中似乎不起作用。为什么没有加载库?我需要做什么才能将 C 库嵌入到 Java 库中以进行分发?我似乎找不到任何特定于此场景的文档。

【问题讨论】:

  • “我有一个适用于 Android 的 Java 库”——您使用什么 Gradle 插件来构建它? java-library 还是 com.android.library? IOW,你想创建一个 JAR 还是一个 AAR?如果答案是 JAR,那就是你的问题。
  • com.android.library
  • “我正在尝试运行单元测试来测试一些包含 C 函数的 Java 函数”——您是否尝试过将其切换到仪器测试?我还没有尝试过 JNI 的单元测试。除此之外,请仔细检查以确认 AAR 中嵌入了您的 C 库。
  • aar 确实包含jni/<arch>/libwrapper.so 处的库,但仅使用assembleRelease 生成。我还没有尝试过仪器化测试
  • “aar 确实包含库”——然后我将专注于在 Android 环境中测试库(仪器测试、报废应用程序等)。 IOW,请确认问题是否严格与单元测试有关。

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


【解决方案1】:

问题在于 JUnit 测试在主机上运行,​​并且在需要 dylib 库的 macOS 上运行,该库默认情况下不构建。有 approaches 让 gradle 构建了这个库,尽管 java.library.path 仍然缺少它,那时我意识到这对我来说太过分了——虽然速度不快,但如果进行仪器测试,它将正常工作而是使用(只需将测试从 src/test 移动到 src/androidTest)。

【讨论】:

    猜你喜欢
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 2011-01-29
    • 2012-06-24
    相关资源
    最近更新 更多