C/C++回调Arkts函数(多线程调用)

1、逻辑需求:

底层C/C++库需要初始化时,设置回调函数,供其它接口回调时使用,其它接口为异步调用。

2、大致实现逻辑

napi层

#include "napi/native_api.h"
#include <thread>

napi_ref cbObj = nullptr; 
napi_threadsafe_function tsfn; 

static void CallJs(napi_env env, napi_value js_cb, void *context, void *data) { 
  napi_get_reference_value(env, cbObj, &js_cb); 
  napi_value argv;
  int i = (*(int *) data);
  napi_create_int32(env, i, &argv); 
  napi_value result = nullptr; 
  napi_call_function(env, nullptr, js_cb, 1, &argv, &result); 
}
static napi_value SetCallback(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value js_cb, work_name; 
    napi_status status; 
    napi_get_cb_info(env, info, &argc, &js_cb, nullptr, nullptr); 
    status = napi_create_reference(env, js_cb, 1, &cbObj); 
    // Set initial_refcount to 0 for a weak reference, >0 for a strong reference. 
    status = napi_create_reference(env, js_cb, 1, &cbObj); 
    status = napi_create_string_utf8(env, "Node-API Thread-safe call from Async work Item", NAPI_AUTO_LENGTH, &work_name); 
    status = napi_create_threadsafe_function(env, js_cb, NULL, work_name, 0, 1, NULL, NULL, NULL, CallJs, &tsfn);
    return nullptr;
}

static void ThreadFunc(void){
    int i = 0;
    while (i < 10) { 
        i += 1;
        napi_call_threadsafe_function(tsfn, &i, napi_tsfn_nonblocking); 
        std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 
    } 
}
static napi_value MainThread(napi_env env, napi_callback_info info) {
    ThreadFunc();
    return nullptr; 
}

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        { "threadTest", nullptr, MainThread, nullptr, nullptr, nullptr, napi_default, nullptr },
        { "setCallback", nullptr, SetCallback, nullptr, nullptr, nullptr, napi_default, nullptr },
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

static napi_module demoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "threadtest",
    .nm_priv = ((void*)0),
    .reserved = { 0 },
};

extern "C" __attribute__((constructor)) void RegisterThreadtestModule(void)
{
    napi_module_register(&demoModule);
}
复制

arkts层

worker.ets

import worker, {  MessageEvents, ThreadWorkerGlobalScope } from '@ohos.worker';
import testNapi from 'libthreadtest.so';
import hilog from '@ohos.hilog';

const workerPort: ThreadWorkerGlobalScope = worker.workerPort;

workerPort.onmessage = (e: MessageEvents) => {
  hilog.info(0x0000, 'testTag', e.data);
  testNapi.threadTest();
}复制

Index.ets

import hilog from '@ohos.hilog';
import testNapi from 'libthreadtest.so';
import worker, { ErrorEvent, MessageEvents } from '@ohos.worker';
import emitter from '@ohos.events.emitter';

let worker1: worker.ThreadWorker = new worker.ThreadWorker('threadtest/ets/workers/worker.ets', { name: "worker1" });

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  // 定义一个eventId为1的事件
  event:emitter.InnerEvent = {
    eventId: 1
  };

  // 收到eventId为1的事件后执行该回调
  callback = (eventData:emitter.EventData) => {
    hilog.info(0x0000, 'testTag', "callback: " + eventData.data?.msg);
    this.message = 'callbackTimes : ' + eventData.data?.msg;
  };

  executeCallback(msg:number) {
    hilog.info(0x3200, 'SD_PVD330', "executeCallback: " + msg + "\n");
    // 定义一个eventId为1的事件,事件优先级为Low
    let event:emitter.InnerEvent = {
      eventId: 1,
      priority: emitter.EventPriority.LOW
    };
    let eventData:emitter.EventData = {
      data: {
        "msg": msg
      }
    };

    // 发送eventId为1的事件,事件内容为eventData
    emitter.emit(event, eventData);
  }

  build() {
    Row() {
      Column() {
        Text( this.message )
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            hilog.info(0x0000, 'testTag', 'before testNapi.threadTest');
            worker1.postMessage('this is a msg to start worker1');
            worker1.onmessage = (e: MessageEvents) => {
              hilog.info(0x0000, 'testTag', "*******worker1 recv :" + e.data);
              let num:number = e.data.data as number
              this.message = 'callbackTimes : ' + num;
              hilog.info(0x0000, 'testTag', this.message);
            };
            worker1.onerror = (e: ErrorEvent) => {
              hilog.info(0x0000, 'testTag', "*******worker1 error :" + e.message);
            }
            hilog.info(0x0000, 'testTag', 'after testNapi.threadTest');
          })
      }
      .width('100%')
    }
    .height('100%')
    .onAppear(() => {
      hilog.info(0x0000, 'testTag', 'onAppear');
      emitter.on(this.event, this.callback);
      testNapi.setCallback(this.executeCallback)
    })
  }
}

复制

其中,回调内用了消息订阅,将回调信息发送给主线程,这里是否需要消息订阅,还没测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

昵称全都被占用

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

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

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

打赏作者

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

抵扣说明:

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

余额充值