ArkTS/js怎样与C++进行交互?

ArkTS/js怎样与C++进行交互?

HarmonyOS
4天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
FengTianYa

​ArkTS/JS可以通过Node-API与C++进行交互。开发者可以使用N-API提供的接口名与三方Node.js一致的接口,目前支持部分接口。例如,提供一个名为Add的native方法,ArkTS侧调用该方法并传入两个number,native方法将这两个number相加并返回到ArkTS侧。此外,ArkTS侧通过import引入native侧的so文件,如import hello from’libhello.so’,意为使用libhello.so的能力,并将名为hello的ArkTS/JS对象给到应用的ArkTS/JS侧,开发者可通过该对象调用到在cpp中开发的native方法。

以下是文档中的示例代码:

Native API在应用工程中的使用指导:​

// entry\src\main\cpp\hello.cpp 
// 引入N-API相关头文件。 
#include "napi/native_api.h" 
 
// 开发者提供的native方法,入参有且仅有如下两个,开发者不需进行变更。 
// napi_env 为当前运行的上下文。 
// napi_callback_info 记录了一些信息,包括从ArkTS侧传递过来参数等。 
static napi_value Add(napi_env env, napi_callback_info info) 
{ 
  // 期望从ArkTS侧获取的参数的数量,napi_value可理解为ArkTS value在native方法中的表现形式。 
  size_t argc = 2; 
  napi_value args = {nullptr}; 
 
  // 从info中,拿到从ArkTS侧传递过来的参数,此处获取了两个ArkTS参数,即arg和arg。 
  napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); 
 
  // 将获取的ArkTS参数转换为native信息,此处ArkTS侧传入了两个number,这里将其转换为native侧可以操作的double类型。 
  double value0; 
  napi_get_value_double(env, args, &value0); 
 
  double value1; 
  napi_get_value_double(env, args, &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 = {nullptr}; 
 
  // 从info中,拿到从ArkTS侧传递过来的参数,此处获取了一个ArkTS参数,即arg。 
  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, 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), 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); 
}
// 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 = entry.nativeCallArkTS((value)=>{return value * 2;}); 
            hilog.info(0x0000, 'testTag', 'Test NAPI nativeCallArkTS ret = %{public}d', ret); 
          }) 
      } 
      .width('100%') 
    } 
    .height('100%') 
  } 
}
// 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; 
分享
微博
QQ
微信
回复
4天前
相关问题
HarmonyOS ArkTSC/C++交互
498浏览 • 1回复 待解决
ArkTSC++之间的交互
1185浏览 • 1回复 待解决
ArkTSC++互相直接调用
1820浏览 • 1回复 待解决
如何实现ArkTSC/C++的数组转换
533浏览 • 1回复 待解决
如何实现ArkTSC/C++的HashMap转换?
976浏览 • 0回复 待解决
如何实现ArkTSC/C++的对象传递
479浏览 • 1回复 待解决
HarmonyOS 原生js交互
95浏览 • 1回复 待解决
ArkTSNative侧如何进行map数据交互
2108浏览 • 1回复 待解决
怎样c\c++开发啊有知道的吗?
4062浏览 • 1回复 待解决
如何在C/C++ 创建ArkTS的对象
2074浏览 • 1回复 待解决
c/c++层主动调用ArkTS存在问题
262浏览 • 1回复 待解决
C++ 如何获取操作 Arkts 实例
797浏览 • 1回复 待解决
C++调用ArkTS 定义的方法
1748浏览 • 1回复 待解决
需要提供c++js通信demo
529浏览 • 1回复 待解决
使用C++进行HarmonyOS开发的问题
431浏览 • 2回复 待解决
C++同步调ArkTS里面的方法
955浏览 • 1回复 待解决
ArkTS层通过接口访问C++层对象
254浏览 • 1回复 待解决
ArkTS对象绑定的C++对象如何回收?
791浏览 • 1回复 待解决
ArkTS调用C++类中的成员函数
1177浏览 • 1回复 待解决
提问
该提问已有0人参与 ,帮助了0人