HarmonyOS鸿蒙Next中团结引擎如何和DevEco Studio的C++互相通信
HarmonyOS鸿蒙Next中团结引擎如何和DevEco Studio的C++互相通信 如题,纯小白,求详细操作过程。注意是C++,不要ArkTs的
开发者您好,请您参考以下方案:
团结引擎开发的游戏适配HarmonyOS,HarmonyOS和OpenHarmony适配的方案一致,文档入口您可以参考官网文档:团结引擎游戏的系统适配。进入之后,您可以参考文档适配指导中6 适配三方库完成。
更多关于HarmonyOS鸿蒙Next中团结引擎如何和DevEco Studio的C++互相通信的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
- DevEco 编写 OpenHarmony 平台 C++ 业务代码并编译 so 库
- so 库导入团结引擎专属鸿蒙插件目录;
- 引擎 C# 通过 DllImport 直接调用 C++ 能力;
- C++ 需要主动推送数据时,使用 TuanjieSendMessage 回调引擎;
- 引擎导出鸿蒙工程,DevEco 整体构建,完成联调与真机运行。
具体可看官方资料:【团结引擎_鸿蒙游戏的新手指导】
团结引擎(Laya)与 DevEco C++ 通信实现如下
一、通信原理概述
技术栈关系
- 团结引擎(Laya):运行在 ArkTS 层,负责游戏逻辑(JavaScript/ArkTS)
- DevEco C++ 模块:通过 NDK 编译为 .so 动态库,提供高性能原生能力
- 通信桥梁:使用 HarmonyOS NAPI 框架实现 ArkTS 与 C++ 的双向数据交换
关键机制
- NAPI 接口:实现跨语言方法调用与回调
- 序列化协议:通过 Sendable 对象实现线程安全的数据传递
二、操作步骤
步骤 1:配置 NDK 工程
创建 Native C++ 模块
在 DevEco Studio 中选择 File > New > Native C++ 模板
配置 CMakeLists.txt
确保 ABI 兼容性(如 arm64-v8a):
cmake_minimum_required(VERSION 3.4.1)
project(LayaBridge)
# 生成动态库
add_library(laya_bridge SHARED bridge.cpp)
# 链接 NAPI 库
target_link_libraries(laya_bridge PUBLIC libace_napi.z.so)
配置 build-profile.json5
声明 NDK 路径:
{
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"abiFilters": ["arm64-v8a"]
}
}
步骤 2:实现 C++ 通信接口
定义跨线程回调结构体
// bridge.cpp
#include "napi/native_api.h"
#include <string>
// 定义回调函数类型
using Callback = std::function<void(const std::string&)>;
static Callback g_layaCallback; // 全局回调
// 注册 ArkTS 回调到 C++
static napi_value RegisterCallback(napi_env env, napi_callback_info info) {
napi_value args;
napi_get_cb_info(env, info, nullptr, nullptr, &args, nullptr);
napi_create_reference(env, args, 1, &g_callbackRef); // 持久化引用
return nullptr;
}
暴露 C++ 函数给 ArkTS
// 声明模块导出函数
static napi_value Init(napi_env env, napi_value exports) {
napi_property_descriptor desc[] = {
{ "registerCallback", nullptr, RegisterCallback, nullptr, nullptr, nullptr, napi_default, nullptr }
};
napi_define_properties(env, exports, sizeof(desc)/sizeof(desc[0]), desc);
return exports;
}
NAPI_MODULE(laya_bridge, Init)
步骤 3:ArkTS 层调用 C++
加载 Native 模块
// Laya 游戏代码中
import native from '@kit.ArkTS';
const nativeBridge = native.load('laya_bridge'); // 对应 CMake 中的库名
nativeBridge.registerCallback((msg: string) => {
console.log('C++消息: ' + msg); // 接收 C++ 回调
});
触发 C++ 函数执行
// 从 Laya 引擎调用 C++ 方法
nativeBridge.invoke('calculateDistance',
{ x1: 10, y1: 20, x2: 30, y2: 40 },
(result) => {
console.log('计算结果: ' + result);
}
);
步骤 4:C++ 调用 ArkTS 回调
// 在 C++ 中触发回调(如计算完成后)
static void SendToLaya(const std::string& result) {
napi_env env = ...; // 从线程安全上下文获取 env
napi_value callback;
napi_get_reference_value(env, g_callbackRef, &callback);
napi_value argv;
napi_create_string_utf8(env, result.c_str(), result.length(), &argv);
napi_call_function(env, nullptr, callback, 1, &argv, nullptr); // 跨线程调用
}
三、调试与验证
断点配置
- 在 DevEco Studio 中设置 Run/Debug Configurations > Debugger > Dual(ArkTS/JS + Native)
- 同时在 ArkTS 和 C++ 代码中打断点
日志查看
使用 hilog 输出 C++ 日志:
#include "hilog/log.h"
OH_LOG_Print(LOG_APP, LOG_INFO, 0, "Bridge", "C++ message sent");
四、注意事项
线程安全
- NAPI 对象禁止跨线程直接操作
- 需通过 napi_create_threadsafe_function 封装
数据类型映射
| ArkTS 类型 | C++ 类型 | 转换接口 |
|---|---|---|
| number | int/double | napi_get_value_int32 |
| string | std::string | napi_create_string_utf8 |
| object | napi_value | napi_get_property |
性能优化
- 高频通信使用 Sendable 对象避免序列化开销
五、环境要求
- 系统版本:HarmonyOS 5.0+
- IDE 版本:DevEco Studio 5.0.4+
- NDK 版本:建议使用最新稳定版
参考资源
- 【鸿蒙开发案例篇】NAPI 实现 ArkTS 与 C++ 间的复杂对象传递
- C/C++代码怎么调用鸿蒙应用中的ArkTS代码?
- 如何使用DevEco Studio进行C/C++代码断点调试
- 华为开发者联盟 - Native C++ 模板示例
提示:完整示例工程可参考华为开发者联盟文档中的 Native C++ 模板。若遇编译问题,请检查 NDK 版本兼容性。
开发者您好!
一、整体架构(一句话看懂)
- 团结引擎侧:C# → P/Invoke 调用 C++ 插件(.so)
- 鸿蒙侧(DevEco C++):通过 N-API / 动态链接 加载同一个 C++ 共享库(.so)
- 双向通信:C++ 作为中间层,两边都能调用它;C++ 再通过 函数指针 / 回调 反向调用两边
你要的是:团结引擎 C# ↔ C++ ↔ DevEco C++(纯原生通道)
二、环境准备
- 安装 团结引擎(Tuanjie),并勾选 OpenHarmony Build Support 模块
- 安装 DevEco Studio(带 Native C++ SDK、NDK)
- 系统:Windows /macOS 均可;架构:arm64-v8a(鸿蒙手机 / 平板)
三、第一步:编写共用的 C++ 库(两边都调用它)
1. 新建 C++ 库项目(或直接写 .h/.cpp)
新建文件夹 SharedCpp,创建 2 个文件:
(1) shared_api.h(对外接口)
#ifndef SHARED_API_H
#define SHARED_API_H
#include <stdint.h>
// 必须加 extern "C",防止C++名称粉碎(关键!)
#ifdef __cplusplus
extern "C" {
#endif
// 1. 简单函数:C++ 加法(两边都能调用)
int32_t Shared_Add(int32_t a, int32_t b);
// 2. 回调类型:用于 C++ → 调用 C# / DevEco C++
typedef void (*SharedMessageCallback)(const char* msg);
// 3. 注册回调(C#/DevEco C++ 把自己的函数传给C++)
void Shared_RegisterCallback(SharedMessageCallback cb);
// 4. C++ 主动发消息(触发回调)
void Shared_SendMessage(const char* msg);
#ifdef __cplusplus
}
#endif
#endif // SHARED_API_H
(2) shared_api.cpp(实现)
#include "shared_api.h"
// 全局保存回调指针
static SharedMessageCallback g_Callback = nullptr;
int32_t Shared_Add(int32_t a, int32_t b) {
return a + b;
}
void Shared_RegisterCallback(SharedMessageCallback cb) {
g_Callback = cb;
}
void Shared_SendMessage(const char* msg) {
if (g_Callback) {
g_Callback(msg); // 回调:C++ → C# / DevEco C++
}
}
四、第二步:编译 C++ 为 .so(给鸿蒙 / 团结引擎用)
方案 A:用 DevEco 编译(推荐,一次编译两边用)
- DevEco 新建 Native C++ 空项目
- 把 shared_api.h / shared_api.cpp 放入 entry/src/main/cpp/
- 修改 CMakeLists.txt(编译成动态库)
cmake_minimum_required(VERSION 3.13)
project(sharedcpp)
# 编译为动态库
add_library(sharedcpp SHARED
shared_api.cpp
)
# 头文件路径
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
- 点击 Build → Make Project
- 生成路径:
entry/build/intermediates/cmake/release/obj/arm64-v8a/libsharedcpp.so
方案 B:用团结引擎编译(略)
- 放入
Assets/Plugins/OHOS/arm64-v8a/ - 团结引擎会自动参与 NDK 编译
五、第三步:团结引擎侧(C# → C++)
1. 放入 .so 和头文件
- 在团结引擎中创建目录:
Assets/Plugins/OHOS/arm64-v8a/libsharedcpp.so
Assets/Plugins/OHOS/include/shared_api.h
- 选中
.so→ Inspector:- Select Platforms: OHOS
- CPU: ARM64
- 勾选 Load On Startup
2. C# 调用 C++(P/Invoke)
新建脚本 NativeComm.cs:
using System;
using System.Runtime.InteropServices;
using UnityEngine;
public class NativeComm : MonoBehaviour
{
// 1. 引入共用C++库
#if UNITY_OPENHARMONY
const string LIB_NAME = "sharedcpp";
#else
const string LIB_NAME = "__Internal";
#endif
[DllImport(LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern int Shared_Add(int a, int b);
[DllImport(LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern void Shared_RegisterCallback(SharedMessageCallback cb);
[DllImport(LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern void Shared_SendMessage(string msg);
// 2. 回调委托(匹配C++的typedef)
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SharedMessageCallback(string msg);
// 3. 保存委托(防止GC回收,关键!)
private static SharedMessageCallback s_Callback;
void Start()
{
// (1) C# → C++:调用加法
int sum = Shared_Add(10, 20);
Debug.Log($"C# 调用 C++ Add: 10+20 = {sum}");
// (2) 注册C#回调(C++将来能调用)
s_Callback = OnCppMessage;
Shared_RegisterCallback(s_Callback);
// (3) C# → C++:发消息
Shared_SendMessage("Hello from Unity C#");
}
// (4) C++ → C#:回调函数
[AOT.MonoPInvokeCallback(typeof(SharedMessageCallback))]
static void OnCppMessage(string msg)
{
Debug.Log($"C# 收到 C++ 回调: {msg}");
}
}
3. 挂载与导出
- 把
NativeComm挂到场景中一个 GameObject - File → Build Settings → OHOS → Build
- 导出 DevEco 工程(后面要导入 DevEco)
六、第四步:DevEco C++ 侧(鸿蒙 C++ → C++ 库)
1. 导入共用库
- 打开刚才团结引擎导出的 DevEco 工程
- 把
libsharedcpp.so放入:
entry/src/main/cpp/libs/arm64-v8a/
- 把
shared_api.h放入:
entry/src/main/cpp/include/
2. 修改 CMakeLists.txt(链接 .so)
cmake_minimum_required(VERSION 3.13)
project(entry)
# 1. 头文件
include_directories(include)
# 2. 库路径
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/libs/arm64-v8a)
# 3. 你的模块
add_library(entry SHARED
native.cpp
)
# 4. 链接共用C++库
target_link_libraries(entry
sharedcpp # 核心!
log
)
3. DevEco C++ 调用(native.cpp)
#include <stdio.h>
#include <string>
#include "napi/native_api.h"
#include "include/shared_api.h"
// 1. 回调:C++ → DevEco C++
void CppMessageFromShared(const char* msg) {
printf("DevEco C++ 收到 C++ 回调: %s\n", msg);
}
// 2. 导出给ArkTS的方法(演示用,你可以纯C++调用)
static napi_value DevEcoCallCpp(napi_env env, napi_callback_info info) {
napi_value result;
// (1) DevEco C++ → C++:调用加法
int sum = Shared_Add(100, 200);
printf("DevEco C++ 调用 C++ Add: 100+200 = %d\n", sum);
// (2) 注册DevEco回调
Shared_RegisterCallback(CppMessageFromShared);
// (3) DevEco C++ → C++:发消息
Shared_SendMessage("Hello from DevEco C++");
// 返回结果给ArkTS(可选)
napi_create_int32(env, sum, &result);
return result;
}
// 3. N-API注册
extern "C" __attribute__((visibility("default")))
napi_value Init(napi_env env, napi_value exports) {
napi_property_descriptor desc[] = {
{"callCpp", nullptr, DevEcoCallCpp, nullptr, nullptr, nullptr, napi_default, nullptr}
};
napi_define_properties(env, exports, sizeof(desc)/sizeof(desc[0]), desc);
return exports;
}
七、双向通信完整流程(最终效果)
- 启动 App
- Unity C# → 调用
Shared_Add(10,20)→ C++ → 返回 30 - Unity C# → 注册
OnCppMessage回调到 C++ - Unity C# →
Shared_SendMessage("Hello Unity")→ C++ - C++ → 回调 → Unity C# 打印:
Hello Unity - DevEco C++ → 调用
Shared_Add(100,200)→ C++ → 返回 300 - DevEco C++ → 注册
CppMessageFromShared回调 - DevEco C++ →
Shared_SendMessage("Hello DevEco")→ C++ - C++ → 回调 → DevEco C++ 打印:
Hello DevEco
真正双向:任何一边调用
Shared_SendMessage,两边都会收到回调(共用同一个 C++ 库)
八、小白常见坑(必看)
-
必须加
extern "C"- 不加:C#/DevEco 找不到函数(名称粉碎)
-
回调必须防 GC
- C# 用静态委托 +
[MonoPInvokeCallback]
- C# 用静态委托 +
-
.so 架构必须匹配
- 鸿蒙真机:arm64-v8a
-
团结引擎导出后必须在 DevEco 重新编译
- 直接运行会报 “库找不到”
在Unity引擎与基于DevEco Studio开发的鸿蒙应用之间进行C++通信,通常是指将您在Unity中编写或集成的C++代码,与鸿蒙应用的C++部分进行交互。这主要通过**原生插件(Native Plugins)**的方式来实现。
具体来说,您可以将C++代码编译成一个动态链接库(.so文件),然后在Unity和鸿蒙应用的C++层分别加载并调用这个库中的函数。
下面是详细的操作过程:
第一步:准备工作 - 编写通用的C++库
首先,您需要创建一个独立的C++项目,编写您希望共享的功能代码。这个库将被两端加载。
-
创建C++库项目
- 在您的电脑上(例如使用Visual Studio、CLion或Code::Blocks)创建一个新的C++项目。
- 将项目类型设置为“动态链接库”(Dynamic-Link Library),这样最终会生成一个 .dll (Windows) 或 .so (Linux/macOS) 文件。
-
编写C++接口
- 在头文件(例如
MySharedLibrary.h)中定义您希望暴露给外界的函数。 - 为了确保跨平台兼容性,建议使用标准的C风格函数(即使用
extern "C"包裹)。
// MySharedLibrary.h #ifdef __cplusplus extern "C" { #endif // 一个简单的示例函数,用于演示通信 int32_t AddNumbers(int32_t a, int32_t b); #ifdef __cplusplus } #endif - 在头文件(例如
-
实现C++函数 在对应的 .cpp 文件中实现这些函数。
// MySharedLibrary.cpp #include "MySharedLibrary.h" int32_t AddNumbers(int32_t a, int32_t b) { return a + b; } -
编译生成库文件 将项目编译成动态链接库。假设最终生成了名为
libMySharedLibrary.so的文件。
第二步:在鸿蒙应用(DevEco Studio)中集成并调用C++库
在团结引擎(Tuanjie Engine)与 DevEco Studio 的混合开发中,C++ 代码的通信主要依赖于 Node-API (N-API)。
简单来说,团结引擎底层本身就是 C++,它通过 Node-API 将接口暴露给 ArkTS/JS 层,而 DevEco 的 C++ 代码同样通过 Node-API 与 ArkTS 交互。因此,ArkTS 是两者通信的“桥梁”,而 C++ 是底层的“执行者”。
以下是实现团结引擎 C++ 与 DevEco C++ 互相通信的详细操作过程:
🏗️ 核心架构原理
- 团结引擎侧 (C++):团结引擎将自身的 C++ 功能(如游戏逻辑、渲染控制)封装成
libtuanjie.so,并通过 Node-API 导出接口。 - 桥梁层 (ArkTS/JS):ArkTS 代码
import团结引擎的.so库,同时也import你自己编写的 DevEco C++.so库。 - DevEco 侧 (C++):你编写自己的 C++ 代码,编译为
.so库,并通过 Node-API 暴露接口给 ArkTS。
通信流向: 团结引擎 C++ <—> ArkTS (调用中转) <—> DevEco C++
🛠️ 详细操作步骤
第一步:准备 DevEco C++ 原生模块
首先,你需要在 DevEco Studio 中创建一个 C++ 原生库。
- 创建 C++ 文件: 在
entry/src/main/cpp目录下创建native_lib.cpp。 - 编写 Node-API 代码: 你需要使用 Node-API 的标准宏来暴露函数。
// entry/src/main/cpp/native_lib.cpp
#include <node.h>
#include <node_object_wrap.h>
// 定义一个 C++ 函数,用于被 ArkTS 调用
void PrintLog(const napi_env env, napi_callback_info info) {
// 这里写你的 C++ 逻辑,比如调用第三方 C++ SDK
printf("DevEco C++: Received message from Tuanjie!\n");
}
// 注册模块
static napi_value Init(napi_env env, napi_value exports) {
// 将 C++ 函数 "PrintLog" 映射为 JS/TS 可调用的 "printLog"
napi_property_descriptor descriptors[] = {
{ "printLog", nullptr, PrintLog, nullptr, nullptr, nullptr, napi_default, nullptr }
};
napi_define_properties(env, exports, sizeof(descriptors) / sizeof(descriptors[0]), descriptors);
return exports;
}
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
- 配置 CMakeLists.txt: 确保你的 C++ 代码被编译成
.so库(例如libnative.so)。
第二步:在团结引擎/ArkTS 层进行桥接
在团结引擎导出的工程或 ArkTS 代码中,你需要同时加载团结引擎的库和你刚才写的 DevEco C++ 库。
- 导入库: 在 ArkTS 文件中(例如
Index.ets或专门的桥接文件):
// 导入团结引擎的库 (通常引擎会自动处理,或者你需要显式导入)
import tuanjie from 'libtuanjie.so';
// 导入你自己写的 DevEco C++ 库
import nativeLib from 'libnative.so';
// 定义一个桥接函数
export function callNativeCppFunction() {
console.info('ArkTS: 准备调用 DevEco C++');
// 调用 DevEco C++ 的函数
nativeLib.printLog();
}
第三步:从团结引擎 C++ 发起调用
这是最关键的一步。团结引擎的 C++ 代码不能直接 #include 你的 DevEco C++ 代码(因为它们编译环境不同,且运行时隔离)。必须通过 ArkTS 中转。
-
团结引擎 C++ -> ArkTS: 在团结引擎的 C++ 代码中,你需要调用引擎提供的接口来发消息给 ArkTS。根据团结引擎的文档,通常使用
SendMessage或类似的机制。假设在团结引擎 C++ 中:
// 团结引擎 C++ 代码 void SendDataToNative() { // 调用引擎暴露给 C++ 的接口,向 TS 层发送消息 // 注意:具体函数名取决于团结引擎的版本,通常是 SendMessage 或类似的 Native 接口 // 这里的 "OnDataReceived" 是你在 TS 层监听的回调名 tuanjie::SendMessage("OnDataReceived", "Hello from Tuanjie C++"); } -
ArkTS 接收并转发: 在 ArkTS 中监听团结引擎的消息,并转发给 DevEco C++。
// 监听团结引擎发来的消息
// 注意:具体监听方式需参考团结引擎文档,此处为逻辑示意
globalThis.tuanjieOnMessage = (msg) => {
if (msg.type === "OnDataReceived") {
console.info("ArkTS: 收到引擎消息 -> " + msg.data);
// 收到消息后,调用 DevEco C++
nativeLib.printLog();
}
};
第四步:反向通信 (DevEco C++ -> 团结引擎 C++)
如果需要 DevEco C++ 主动通知团结引擎:
-
DevEco C++ -> ArkTS: 在 C++ 中使用 Node-API 回调 JS。
// native_lib.cpp // 这是一个异步通知的例子 void NotifyTuanjie(napi_env env, void* data) { // 获取 JS 层的回调函数并调用,传递数据 // ... (Node-API 标准回调代码) } -
ArkTS -> 团结引擎 C++: ArkTS 收到 C++ 回调后,调用团结引擎提供的接口。
// ArkTS import tuanjie from 'libtuanjie.so'; // 假设这是 DevEco C++ 的回调 function onNativeEvent(data) { // 调用团结引擎接口,将数据传回引擎 tuanjie.TuanjieSendMessage("GameLogic", "OnNativeEvent", data); }
⚠️ 关键注意事项
-
线程模型:
- ArkUI 线程:负责 UI 绘制,不能进行耗时操作。
- TuanjieMain 线程:团结引擎的主线程(Worker 线程)。
- C++ 线程:Node-API 的回调可能在后台线程触发。
- 警告:千万不要在 DevEco C++ 的后台线程直接操作 ArkUI。如果需要更新 UI,必须通过
postMessage回到 ArkUI 线程。
-
数据序列化: C++ 与 ArkTS 之间传递的数据通常限制为可序列化的类型(字符串、数字、JSON 对象)。如果需要传递大量二进制数据(如图片流),建议使用
ArrayBuffer。 -
构建配置: 在团结引擎导出工程后,你需要将 DevEco 的 C++ 源码或编译好的
.so放入导出工程的entry/src/main/cpp目录,并修改CMakeLists.txt将其链接进去,或者作为独立的.so依赖引入。
总结
不要试图让两个 C++ 代码直接“握手”。标准路径是: Tuanjie C++ ➔ Tuanjie Native API ➔ ArkTS ➔ Node-API ➔ DevEco C++。
这得去团结引擎那看一下吧
-
导出接口 :在团结引擎(Unity)中,将需要被鸿蒙调用的C#方法封装并导出为C/C++接口。
-
加载与调用 :在鸿蒙应用中,使用 System.loadLibrary 加载团结引擎编译生成的动态链接库( .so 文件),然后通过C/C++函数指针直接调用这些导出的接口。
-
反向通信 :鸿蒙应用若需通知团结引擎,可以通过在第一步导出的接口中注册回调函数,再由团结引擎在特定时机触发该回调来实现。
可以到团结引擎官网问问
在 HarmonyOS Next 中,团结引擎(Unity)与 DevEco Studio 的 C++ 通信通过 Unity 原生插件(Native Plugin)实现。Unity 侧使用 C# 的 [DllImport] 或 [UnityEngine.Scripting.Preserve] 属性加载 C++ 动态库(.so)。C++ 代码在 DevEco Studio 中编译,利用 OHOS NAPI 或标准 C++ 接口导出函数,即可完成数据与逻辑交互。
团结引擎(Unity中国版)与DevEco Studio的C++通信,本质是通过动态库(.so)完成原生调用。在 HarmonyOS Next 上,C# 与 C++ 互操作完全依赖 NDK 导出的 C 接口,不涉及 ArkTS。
核心流程:
- 在 DevEco Studio 中创建 Native C++ 库工程,编写需要导出的函数并使用
extern "C"修饰。 - 编译生成
.so(通常选 arm64-v8a),注意build-profile.json5中的 ABI 过滤。 - 将
.so放入团结引擎项目的Assets/Plugins/OpenHarmony/libs/arm64-v8a/目录。 - 在团结引擎 C# 脚本里用
[DllImport("函数名")]声明并调用。 - 需要 C++ 回调 C# 时,通过
Marshal.GetFunctionPointerForDelegate将委托转为函数指针传入 C++,C++ 侧用typedef void (*Callback)(...);接收并回调。
C++ 导出示例 (MyPlugin.cpp)
#include <string>
extern "C" {
const char* GetMessage() {
static std::string msg = "Hello from C++";
return msg.c_str();
}
}
C# 调用 (Unity脚本)
using System.Runtime.InteropServices;
using UnityEngine;
public class PluginBridge : MonoBehaviour {
[DllImport("GetMessage")]
private static extern System.IntPtr GetMessage_Internal();
void Start() {
string msg = Marshal.PtrToStringAnsi(GetMessage_Internal());
Debug.Log(msg);
}
}
DllImport 里直接填函数名即可(无需 lib 前缀和 .so 后缀),团结引擎会在 OpenHarmony 平台自动解析。
C++ 回调示例
C# 定义委托,获取函数指针传入 C++,C++ 保存并在合适时机调用。注意生命周期,避免委托被 GC 回收。
整个过程不需要接触 ArkTS,所有通信链路均基于 C 接口。插件放置目录严格按照 OpenHarmony 子目录,团结引擎打包时会自动拷贝至对应 HAP 的 libs。

