简体   繁体   English

在 Java 库中嵌入 C 库

[英]Embed C library in Java library

I have a Java library for Android which I distribute to third party developers, and I want to embed a C library in it.我有一个用于 Android 的 Java 库,我将它分发给第三方开发人员,我想在其中嵌入一个 C 库。 I've added the library to the project via CMake:我已通过 CMake 将该库添加到项目中:

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

To the library's build.gradle I've added:我在图书馆的 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+"
        }
    }
}

In the library, I load the C library with:在库中,我加载了 C 库:

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

I'm trying to run a unit test to test some of the Java functions which wrap the C functions, and I get the exception:我正在尝试运行单元测试来测试一些包装 C 函数的 Java 函数,但出现异常:

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

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

This works when I'm linking the C library in an App, but doesn't seem to work in a Java library.当我在应用程序中链接 C 库时,这有效,但在 Java 库中似乎不起作用。 Why is the library not loaded?为什么库没有加载? What do I need to do to embed the C library in a Java library for distribution?我需要做什么才能将 C 库嵌入到 Java 库中进行分发? I can't seem to find any documentation specific to this scenario.我似乎找不到任何特定于这种情况的文档。

The problem is that JUnit tests run on the host machine, and on macOS that requires a dylib library, which is not built by default.问题是 JUnit 测试在主机上运行,​​在需要 dylib 库的 macOS 上运行,默认情况下它不是构建的。 There are approaches which make gradle build this library, although it was still missing from java.library.path , and at that point I realised it was a hack too far for me – while not as fast, it will work correctly if an instrumented test is used instead (just move the test from src/test to src/androidTest ).有一些方法可以让 gradle 构建这个库,尽管java.library.path中仍然缺少它,那时我意识到这对我来说太过分了——虽然没有那么快,但如果一个仪器测试它会正常工作改为使用(只需将测试从src/test移动到src/androidTest )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM