Skip to main content
本指南演示如何将在 开发环境 中独立编译的 C/C++ 库集成到 arkffi 项目中,并通过 dlopen 调用其函数。

步骤概览

  1. 在 开发环境 中创建 C/C++ 库项目
  2. 使用 HarmonyOS NDK 交叉编译为 arm64-v8a 架构
  3. 将编译产物放入 entry/libs/arm64-v8a/
  4. 在 ArkTS 中通过 dlopen 加载并调用

1. 创建外部库项目

自行创建 C/C++ 库项目。 源代码 library.cpp
extern "C" 防止 C++ 编译器对函数名进行改编(name mangling),确保 dlsym("hello") 能正确找到符号。如果不加,编译后的符号名会被改成 _Z5hellov,导致 dlopen 无法识别。
CMakeLists.txt

2. 交叉编译为 HarmonyOS

在 开发环境 中使用 HarmonyOS NDK 的交叉编译器进行编译:
确保使用 HarmonyOS NDK 的 aarch64-linux-ohos-* 工具链,而非 macOS 自带的 Clang。-fPIC 是编译共享库必需的选项。

3. 放置编译产物

将编译生成的 libhello.so 放入项目的以下目录:
如果项目还支持 x86_64 模拟器,需要在 entry/libs/x86_64/ 下也放置对应架构的编译产物。本示例仅编译 arm64-v8a,因此 abiFilters 也仅包含此架构。

4. 配置 abiFilters

确保 library/build-profile.json5abiFilters 包含编译产物对应的架构:

5. 在 ArkTS 中调用

注意事项

  • 返回 const char* 的函数必须使用 returns: FFIType.int64 而非 returns: FFIType.CString,因为底层分发器将 's' 编码视为参数类型,不处理为返回类型。
  • 拿到指针后需通过 CString 类读取实际字符串内容。
  • 确保库已用 extern "C" 编译,否则 dlsym 因名字改编而找不到函数。
  • 关闭库后不要再调用其符号,否则行为未定义。

完整示例

请参见项目中的测试用例:

故障排查