HarmonyOS ArkTS与c++交互通信

本文详细介绍了如何在Android项目中创建NativeC++模块,并通过NAPI进行C++回调与ETS的交互,包括配置CMakeLists.txt和build-profile.json,以及主调接口和回调接口的实现。
摘要由CSDN通过智能技术生成

一、创建Native C++ Module

1、右键项目->new->module

如图:

2、修改build-profile.json5配置

"externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt",
      "arguments": "-v -DOHOS_STL=c++_shared",
      "abiFilters": [
//        "armeabi-v7a",
//        "x86_64",
        "arm64-v8a"
      ],
      "cppFlags": ""
    }

3、CMakeLists.txt 配置如下:

# the minimum version of CMake.
cmake_minimum_required(VERSION 3.4.1)
project(MyApplication43)

set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})

include_directories(${NATIVERENDER_ROOT_PATH}
                    ${NATIVERENDER_ROOT_PATH}/include)

add_library(application SHARED SRRtcVideoEngineNapi.cpp SRRtcRoomCallBackNapi.cpp)
target_link_libraries(application PUBLIC libace_napi.z.so)

二、代码实现

1、主调接口实现

NAPI中缓存回调接口的变量,便于后面回调给TS

napi_value SRRtcVideoEngineNapi::setRRoomCallBack(napi_env env, napi_callback_info info) {
    LogE("setRRoomCallBack---一个参数:ISRoomCallBack");
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    if (status != napi_ok) {
        napi_throw_error(env, "", "");
        return nullptr;
    }
    // 缓存回调函数全局变量,回调ets用
    if (SRGlobalvar::napi_CallbackReference == nullptr) {
        LogE("setRRoomCallBack===new NapiCallBack()");
        SRGlobalvar::napi_CallbackReference = new NapiCallBack(); // 创建缓存函数
    }
    napi_create_reference(env, args[0], 1, &SRGlobalvar::napi_CallbackReference->roomCallBack_napi);
    SRGlobalvar::napi_CallbackReference->env = env;
    // 调用 底层sdk : RRoomControlMgr.setCallBack
    RResult rResult = sr_engineSdk->setRRoomCallBackRtcEngine();
    return SRGlobalvar::returnResult(env, rResult);
}

2、回调接口实现

通过缓存的env,callback对象,调用napi_call_function方法将数据传回给ts

void SRRtcRoomCallBackNapi::onRoomJoinConfirm(RResult rResult, const RRoomInfo &roomInfo) {
    // 处理 onRoomJoinConfirm 通知
    LogE("回调消息---SRRtcRoomCallBack:onRoomJoinConfirm ");
    // 转换N-API对象
    napi_value roomInfo_napi = SRGlobalvar::convertToSRRoomInfo(SRGlobalvar::napi_CallbackReference->env, roomInfo);
    napi_value rResult_napi = SRGlobalvar::convertToSRResult(SRGlobalvar::napi_CallbackReference->env, rResult);
    // 传递给TS
    napi_value callback;
    napi_get_reference_value(SRGlobalvar::napi_CallbackReference->env,
                             SRGlobalvar::napi_CallbackReference->roomCallBack_napi, &callback);
    napi_value jsMethod;
    napi_get_named_property(SRGlobalvar::napi_CallbackReference->env, callback, "onRoomJoinConfirm", &jsMethod);
    napi_value argv[] = {rResult_napi, roomInfo_napi};
    napi_value callbackResult = nullptr;
    napi_call_function(SRGlobalvar::napi_CallbackReference->env, nullptr, jsMethod, 2, argv, &callbackResult);
}

三、ets的接收c++传回的数据

1、index.d.ts 代码增加接口

function setRRoomCallBack(sroomCallback: ISRoomCallBack): SRReult

2、回调接口SRoomCallBack.ets

export class SRoomCallBack implements ISRoomCallBack {
  onRoomJoinConfirm(rResult: SRReult, roomInfo: SRRoomInfo) {
    SRLog.i(TAG, `onRoomJoinConfirm==回调测试完成=rResult:${JsonUtil.jsonToString(rResult)}\n roomInfo:${JsonUtil.jsonToString(roomInfo)}`)

  }
}

3、调用

import srrtcNapi from 'librtcvideo.so';

  setRRoomCallBackRtcEngine(callback: ISRoomCallBack) {
    let srResult = srrtcNapi.setRRoomCallBack(callback)
    SRLog.i(TAG, "setRRoomCallBackRtcEngine===srresult:" + JsonUtil.jsonToString(srResult))
  }

                
QML 与 C++ 交互的过程一般分为以下几个步骤: 1. 定义 C++ 类并注册到 QML 中 你需要在 C++ 中定义一个类,该类封装了你想要实现的功能。同时,你需要使用 `qmlRegisterType` 函数将该类注册到 QML 中,以便在 QML 中使用该类。 例如,你可以定义一个名为 `MyClass` 的类,并将其注册到 QML 中: ```cpp class MyClass : public QObject { Q_OBJECT public: Q_INVOKABLE int myFunction(int arg) { // 实现你的功能 } }; qmlRegisterType<MyClass>("com.example", 1, 0, "MyClass"); ``` 在上面的代码中,`Q_INVOKABLE` 用于声明 `myFunction` 函数可从 QML 中调用,`qmlRegisterType` 函数用于将 `MyClass` 类注册到 QML 中。`"com.example"` 表示注册的命名空间,`1` 和 `0` 表示主版本号和次版本号,`"MyClass"` 是在 QML 中使用的类名。 2. 在 QML 中使用 C++ 类 在 QML 中使用 C++ 类时,你需要使用 `import` 语句导入该类所在的命名空间。然后,你可以通过该命名空间来访问该类。例如: ```qml import com.example 1.0 MyClass { id: myClass } Button { onClicked: { var result = myClass.myFunction(42) // 处理返回值 } } ``` 在上面的代码中,`import` 语句用于导入 `com.example` 命名空间,`MyClass` 用于创建一个 `MyClass` 实例,`id` 属性用于设置实例的标识符,`Button` 用于创建一个按钮,`onClicked` 事件处理程序中调用了 `myFunction` 函数,并处理了它的返回值。 3. 在 C++ 中访问 QML 中的对象 如果你需要从 C++ 中访问 QML 中的对象,你可以使用 `QQuickItem` 类提供的 `findChild` 函数。例如: ```cpp QQuickItem *item = qmlEngine.rootObjects().value(0)->findChild<QQuickItem*>("myItem"); if (item) { // 处理 item 对象 } ``` 在上面的代码中,`qmlEngine.rootObjects()` 函数返回 QML 引擎中所有的根对象,`value(0)` 返回第一个根对象,`findChild` 函数用于查找名为 `"myItem"` 的子对象。 以上就是 QML 与 C++ 交互的基本步骤。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ada

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值