N-API接口实现ArkTS/TS/JS和C/C++之间的交互

N-API接口实现ArkTS/TS/JS和C/C++之间的交互

HarmonyOS
2024-05-23 22:01:53
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
sheeny2000

本文主要介绍如何实现ArkTS/TS/JS和C/C++之间的交互

1. 提供一个名为Add的native方法,ArkTS侧调用该方法并传入两个number,native方法将这两个number相加并返回到ArkTS侧。

2. 提供一个名为NativeCallArkTS的native方法,ArkTS侧调用该方法并传入一个ArkTS function,native方法中调用这个ArkTS function,并将其结果返回ArkTS侧。

使用的核心API

napi_get_cb_info

napi_call_function

核心代码解释

.cpp代码

#include "napi/native_api.h" 
static napi_value Add(napi_env env, napi_callback_info info) 
{ 
  // 期望从ArkTS侧获取的参数的数量 
  size_t argc = 2; 
  napi_value args[2] = {nullptr}; 
    
  // 从info中,拿到从ArkTS侧传递过来的参数,此处获取了两个ArkTS参数,即arg[0]和arg[1]。 
  napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); 
​ 
  // 将获取的ArkTS参数转换为native信息,此处ArkTS侧传入了两个number,这里将其转换为native侧可以操作的double类型。 
  double value0; 
  napi_get_value_double(env, args[0], &value0); 
​ 
  double value1; 
  napi_get_value_double(env, args[1], &value1); 
    
  // native侧的业务逻辑,这里简单以两数相加为例。 
  double nativeSum = value0 + value1; 
    
  // 此处将native侧业务逻辑处理结果转换为ArkTS值,并返回给ArkTS。 
  napi_value sum; 
  napi_create_double(env, nativeSum , &sum); 
  return sum; 
} 
​ 
static napi_value NativeCallArkTS(napi_env env, napi_callback_info info) 
{ 
  // 期望从ArkTS侧获取的参数的数量,napi_value可理解为ArkTS value在native方法中的表现形式。 
  size_t argc = 1; 
  napi_value args[1] = {nullptr}; 
    
  // 从info中,拿到从ArkTS侧传递过来的参数,此处获取了一个ArkTS参数,即arg[0]。 
  napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); 
    
  // 创建一个ArkTS number作为ArkTS function的入参。 
  napi_value argv = nullptr; 
  napi_create_int32(env, 10, &argv); 
    
  napi_value result = nullptr; 
  // native方法中调用ArkTS function,其返回值保存到result中并返到ArkTS侧。 
  napi_call_function(env, nullptr, args[0], 1, &argv, &result); 
    
  return result; 
} 
​ 
EXTERN_C_START 
// Init将在exports上挂上Add/NativeCallArkTS这些native方法,此处的exports就是开发者import之后获取到的ArkTS对象。 
static napi_value Init(napi_env env, napi_value exports) 
{ 
  // 函数描述结构体,以Add为例,第三个参数"Add"为上述的native方法, 
  // 第一个参数"add"为ArkTS侧对应方法的名称。 
  napi_property_descriptor desc[] = { 
      { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }, 
      { "nativeCallArkTS", nullptr, NativeCallArkTS, nullptr, nullptr, nullptr, napi_default, nullptr }, 
  }; 
  // 在exports这个ArkTS对象上,挂载native方法。 
  napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 
  return exports; 
} 
EXTERN_C_END 
​ 
// 准备模块加载相关信息,将上述Init函数与本模块名等信息记录下来。 
static napi_module demoModule = { 
  .nm_version =1, 
  .nm_flags = 0, 
  .nm_filename = nullptr, 
  .nm_register_func = Init, 
  .nm_modname = "entry", 
  .nm_priv = ((void*)0), 
  .reserved = { 0 }, 
}; 
​ 
// 打开so时,该函数将自动被调用,使用上述demoModule模块信息,进行模块注册相关动作。 
extern "C" __attribute__((constructor)) void RegisterHelloModule(void) 
{ 
  napi_module_register(&demoModule); 
}

.ets代码

// entry\src\main\ets\pages\index.ets 
​ 
import hilog from '@ohos.hilog'; 
// 通过import的方式,引入native能力。 
import entry from 'libentry.so' 
​ 
@Entry 
@Component 
struct Index { 
​ 
build() { 
  Row() { 
    Column() { 
      // 第一个按钮,调用add方法,对应到native侧的Add方法,进行两数相加。 
      Button('ArkTS call C++') 
        .fontSize(50) 
        .fontWeight(FontWeight.Bold) 
        .onClick(() => { 
          hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); 
          hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', entry.add(2, 3)); 
        }) 
      // 第二个按钮,调用nativeCallArkTS方法,对应到native的NativeCallArkTS,在native中执行ArkTS function。 
      Button('C++ call ArkTS') 
        .fontSize(50) 
        .fontWeight(FontWeight.Bold) 
        .onClick(() => { 
          hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); 
          let ret: number = entry.nativeCallArkTS((value: number)=>{return value * 2;}); 
          hilog.info(0x0000, 'testTag', 'Test NAPI nativeCallArkTS ret = %{public}d', ret); 
        }) 
    } 
    .width('100%') 
  } 
  .height('100%') 
} 
}

d.ts代码

// entry\src\main\cpp\types\libentry\index.d.ts 
// native侧暴露给ArkTS侧接口的声明。 
export const add: (a: number, b: number) => number; 
export const nativeCallArkTS: (a: object) => number;

实现效果

适配的版本信息

IDE:DevEco Studio 4.0.1.601

SDK:HarmoneyOS 4.0.10.11

分享
微博
QQ
微信
回复
2024-05-24 21:49:11
相关问题
ArkTSC++之间交互
388浏览 • 1回复 待解决
如何实现ArkTSC/C++HashMap转换?
361浏览 • 0回复 待解决
tsc++传递数组,c++层如何解析
467浏览 • 1回复 待解决
如何在C/C++ 创建ArkTS对象
713浏览 • 1回复 待解决
C++调用ArkTS 定义方法
479浏览 • 1回复 待解决
C++ 如何获取操作 Arkts 实例
388浏览 • 1回复 待解决
ArkTSC++互相直接调用
456浏览 • 1回复 待解决
如何修改C++版本?C++支持情况?
309浏览 • 1回复 待解决
c++侧可以直接调用tsstatic方法吗?
592浏览 • 1回复 待解决
ArkTS对象绑定C++对象如何回收?
350浏览 • 1回复 待解决
ArkTS调用C++类中成员函数
474浏览 • 1回复 待解决
c++ 有vp2px 接口么?
438浏览 • 1回复 待解决
C++同步调ArkTS里面的方法
367浏览 • 1回复 待解决
需要提供c++js通信demo
285浏览 • 1回复 待解决