我有一个Rust库,它是我为Android编译的静态库(Eng.a),这个库包含一些C兼容(FFI)函数.I've already figured out how to bind and call this library from Java.现在我想从C++调用这些函数(直接调用,不使用JNI).

编译完这个库后,我将生成的文件放在PROJECT_ROOT/android/jniLibs以下,这是Android自动将它们打包到应用程序中的默认位置:

android
  - jniLibs
    - arm64-v8a
       - engine.a
    - armeabi-v7a
       - engine.a
... // so on for the rest of supported archs

我已经生成了一个包含与C兼容的函数的头文件(Engineering.h使用cbindgen,所有函数都用no_mangleextern "C"正确地进行了注释),并将其与我的源代码C++放在一起.这在iOS上已经起作用了,但在Android上,我遇到了一个未定义的符号错误.

Android Studio对导入的标题很满意,并且没有在编辑器中显示任何错误:

#include "engine.h"

...

int res = my_rust_fn();

我的CMakeLists.txt:

        ${PACKAGE_NAME}
        SHARED
    ../cpp/bindings.cpp # contains my C++ that should call the functions in engine.h
    ../cpp/engine.h
    cpp-adapter.cpp
)

include_directories(
    ../cpp
)

set_target_properties(
  ${PACKAGE_NAME} PROPERTIES
  CXX_STANDARD 17
  CXX_EXTENSIONS OFF
  POSITION_INDEPENDENT_CODE ON
)

find_package(ReactAndroid REQUIRED CONFIG)
find_package(fbjni REQUIRED CONFIG)


target_link_libraries(
  ${PACKAGE_NAME}
  fbjni::fbjni
  ReactAndroid::jsi
  ReactAndroid::turbomodulejsijni
  ReactAndroid::react_nativemodule_core
  android
)

但是,当编译代码时,我在my_rust_fn调用时得到一个未定义的符号:

ld: error: undefined symbol: my_rust_fn
>>> referenced by bindings.cpp:91

我还try 使用静态库的名称向cmake列表中添加find_package,但没有成功,它只是抛出一个错误:

find_package(engine REQUIRED CONFIG)

target_link_libraries(
$(PACKAGE_NAME)
engine
...
)

有什么建议我可能做错了什么吗?

推荐答案

多亏了@Botje,他为我指明了正确的方向.仅包括头文件是不够的.链接器需要知道正确的.a文件的位置,才能在编译时正确地链接它.

我在我的CMakeLists.txt美元中添加了以下内容:

add_library(engine STATIC IMPORTED)
set_target_properties(engine PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/engine.a)

target_link_libraries(
  ${PACKAGE_NAME}
  engine

告诉编译器需要链接到哪个特定于体系 struct 的版本.

Android相关问答推荐

在Android Studio中陷入了不兼容的Gradle版本的循环

ENV变量在gradle进程中没有更新

如何使用Gradle风味在两个Kotlin导入(Google vs Amazon Java billing library)之间进行 Select ?

如何清除导航抽屉中以前 Select 的项目(Jetpack Compose)

fillMaxHeight中的分数在列内不起作用(android jetpack compose)

在Jetpack Compose中实现焦点突出的最佳方式?

数据绑定在Android中等待填充值时显示未填充的值

如何在Jetpack Compose中将对象的移动从一个路径平滑地切换到另一个路径?

在Jetpack Compose中,我可以配置动画以恒定的速度而不是恒定的时间运行吗?

Android 12+BLE字节不同

Android 导航 - 定义参数

修复报错 RecyclerView: No adapter attached;跳过布局

如何仅使用您的 Android 应用程序定位平板电脑?

通过 adb 解压并重新安装后 Android 应用程序崩溃

如何从包装在泛型中的 retrofit 调用中检索密钥?

如何正确地将图像上传到 Jetpack Compose 中的 LazyList 中的项目?

缺少类 com.google.android.datatransport.runtime.ForcedSender

在android studio中使用wifi配对设备的问题

Jetpack 使用 Canvas 组成半圆

在 Jetpack Compose 中 Select 要省略的文本