我有一个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相关问答推荐

编写Inbox需要具有匹配兼容性的Kotlin版本

Android可组合继承?

Android 14无法删除已配置的文件

安卓Gradle看不到dagger 柄

更改Jetpack Compose中选定的选项卡底线 colored颜色

两首合成曲的喷气背包动画

jetpackcompose-如何对解析后的复杂对象进行状态提升?

如何在Jetpack Compose中创建这个圆形?

有没有什么方法可以让Beeware在安卓手机上显示图片?

Hilt+Worker NoSuchMethodException:<;init>;[class android.content.Context,class androidx.work.WorkerParameters]

Android 12+BLE字节不同

如何显示具体的商品数量?

使用 JNI 从 Android 应用程序中使用 Kotlin/Native 预构建共享库

Android Compose 为什么 Checkbox 在父对象可点击时需要 onCheckChanged?

在 Jetpack Compose 中对齐行项目

AirDroid Business 如何能够从屏幕截图中排除覆盖?

compose 更改列表元素但lazyColumn不更改

删除一对多关系室 Kotlin 中的所有值

Jetpack Compose Material3 - switch 标签

Android全屏AlertDialog