当前栏目
三方库移植之NAPI开发[2]C/C++与JS的数据类型转换
在《三方库移植之NAPI开发[1]—Hello OpenHarmony NAPI》通过一个Hello OpenHarmony NAPI样例讲述了NPAI接口开发基础知识。本文在其基础上修改hellonapi.cpp文件,介绍JS类型和C/C++数据类型之间的转换。
- 开发基于最新的OpenHarmony3.2Beta3版本及其对应SDK。标准系统开发板为润和软件dayu200。
笔者刻苦学习了三方库NAPI开发的一些皮毛,将学习经验分享如下:
演示视频:https://ost.51cto.com/show/18126
通过本文您将熟悉,通过NAPI框架:
- 如何获取JS传递过来的参数。
- 如何将JS传递过来的参数(NAPI框架已封装为napi_value类型)转换成C/C++类型值用于计算。
- 如何将C/C++类型的值转换成JS类型作并返回。
通过NAPI框架进行C/C++与JS数据类型的转换
- OpenHarmony NAPI将ECMAScript标准中定义的Boolean、Null、Undefined、Number、BigInt、String、Symbol和Object八种数据类型,以及函数对应的Function类型,统一封装成napi_value类型,下文中表述为JS类型,用于接收ArkUI应用传递过来的数据及返回数据给ArkUI应用。
ECMAScript是一种由Ecma国际(通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScript或JScript,所以它可以理解为是JavaScript的一个标准,但实际上后两者是ECMA-262标准的实现和扩展。
- 下面通过扩展一个简单的接口——Add(num1, num2)讲述具体细节,接口使用同步方式实现,NAPI的同步方式调用的扩展API代码处理流程如下图。
.cpp源码实现
- 在《三方库移植之NAPI开发[1]—Hello OpenHarmony NAPI 》一文的基础上修改hellonapi.cpp文件,其余文件不变。
- hellonapi.cpp内容如下:
.cpp源码解析
注册NAPI模块、添加接口声明
接口业务实现C/C++代码
获取参数
- NAPI定义API方法时的接收参数为(napi_env, napi_callback_info)
- 其中napi_callback_info为上下文的信息。
- NAPI提供了napi_get_cb_info()方法可从napi_callback_info中获取参数列表、this及其他数据。
napi_get_cb_info函数在ohos3.2beta3源码foundation/arkui/napi/native_engine/native_api.cpp中。
napi_get_cb_info函数说明如下:
- 参数说明:
- [in] env: 传入接口调用者的环境,包含js引擎等,由框架提供,默认情况下直接传入即可。
- [in] cbinfo: napi_callback_info对象,上下文的信息。
- [in-out] argc: argv数组的长度。若napi_callback_info中实际包含的参数的个数大于请求的数量argc,将只复制argc的值所指定数量的参数只argv中。若实际的参数个数小于请求的数量,将复制全部的参数,数组多余的空间用空值填充,并将参数实际长度写入argc。
- [out] argv: 用于接收参数列表。
- [out] this_arg: 用于接收this对象。
- [out] data: NAPI的上下文数据 返回值:返回napi_ok表示转换成功,其他值失败。下面的返回napi_status方法一样。
- 在Add方法中,调用napi_get_cb_info函数:
JS类型值转换为C/C++类型的值
- 此示例中传入的参数是Javascript值类型,被NAPI框架封装成统一的唯一类型——napi_value类型,为了能够进行计算,我们需要获取其对应在C/C++中的类型的值。
- NAPI提供了包括以下方法以便获取不同类型的值(ohos3.2beta3源码foundation/arkui/napi/native_engine/native_api.cpp中)
- napi_get_value_double
- napi_get_value_int32
- napi_get_value_uint32
- napi_get_value_int64
- napi_get_value_bool
- napi_get_value_string_latin1(Copies LATIN-1 encoded bytes from a string into a buffer)
- napi_get_value_string_utf8(Copies UTF-8 encoded bytes from a string into a buffer)
- napi_get_value_string_utf16
- napi_get_value_external
- napi_get_value_bigint_int64
- napi_get_value_bigint_uint64
- napi_get_value_bigint_words
- 此示例hellonapi.cpp中使用到了napi_get_value_double方法,函数定义如下:
参数说明:
- [in] env: 传入接口调用者的环境,包含js引擎等,由框架提供,默认情况下直接传入即可。
- [in] value: 传入要转换的napi_value类型数据对象(可视为一个JS对象)。
- [out] result: 转换出对应类型(double)结果。 返回值:返回napi_ok表示转换成功,其他值失败。
获取参数的C/C++类型的值前,需要先判断值的类型,本示例需要判断传入参数的JS值必须为number类型
- NAPI框架提供了napi_typeof方法用于获取指定对象的类型,其函数定义如下:
参数说明:
- [in] env: 传入接口调用者的环境,包含js引擎等,由框架提供,默认情况下直接传入即可。
- [in] value: 传入要转换的napi_value类型数据对象(可视为一个JS对象)。
- [out] result: 返回value参数对应的JS类型。
- napi_valuetype对应了ECMAScript标准中定义的Boolean、Null、Undefined、Number、BigInt、String、Symbol和Object八种数据类型,以及函数对应的Function类型。
- 另外,napi_valuetype还包括了一个napi_external类型,其表示没有任何属性也没有任何原型的对象。
综上所述参数类型判断及值转换,示例代码如下:
计算结果转换为JS类型并返回
- 计算的结果是C/C++类型,需要转换成NAPI node_value类型返回给JS。
- NAPI提供了一些方法以便将C/C++不同类型的值转为node_value类型,返回给JS代码。例如:
- napi_create_double
- napi_create_int32
- napi_create_uint32
- napi_create_int64
- napi_create_string_latin1
- napi_create_string_utf8
- napi_create_string_utf16
- 以napi_create_double方法为例,函数定义如下:
参数说明:
[in] env: 传入接口调用者的环境,包含js引擎等,由框架提供,默认情况下直接传入即可。
[in] value: 传入要转换的double类型数据值。
[out] result: 转换出结果。
ArkUI应用实现代码
ArkUI应用实现目录结构。
index.ets内容如下:
index.ets
效果图如下:
index.ets解析
- 参数说明
字段 | 类型 | 说明 |
tittle | string | 标题 |
message | string | 说明 |
tipsNum1 | number | 提示输入第一个参数 |
tipsNum2 | number | 提示输入第二个参数 |
tipsResult | string | 提示结果 |
buttonSubmit | string | 计算按钮名称 |
result | string | 结果 |
num1 | number | 输入的第一个数 |
num2 | number | 输入的第二个数 |
- 设置参数
- 界面实现
- 绑定事件、关联参数
两个TextInput组件分别绑定onChange事件,并分别关联num1,num2来记录输入的参数。
- Button组件添加点击事件,调用hellonapiu.cpp中的Add方法(调用js中的add,add和Add已经在napi.cpp中绑定)。
- 通过NAPI框架输入到C的Add函数的JS参数是num1和num2,输出的JS参数是result。
@ohos.hellonapi.d.ts接口文档
总结
hellonapi.cpp:
index.ets:
相关文章
- html字符转码表
- VS Code前端常用插件推荐,搭建JQuery、Vue等开发环境
- 写jquery用的软件有哪些
- Pure-Highlightjs(Mac风格) – WordPress代码高亮插件
- 面向前端工程师的设计模式-适配器模式
- 5、页脚HTML代码定制篇 - 博客界面改造文章(202203)
- 4、博客侧边栏公告HTML代码定制篇 - 博客界面改造文章(202203)
- 3、页首HTML代码定制篇 - 博客界面改造文章(202203)
- 2、页面CSS样式定制篇 - 博客界面改造文章(202203)
- js 遍历数组、对象的几种方式
- JS ES6 模块化开发入门
- jQuery 自定义网页滚动条样式插件 mCustomScrollbar 的介绍和使用方法
- jQuery鼠标指针光标移动特效
- jquery动感漂浮导航菜单代码分享
- 【JS动态效果】如何jquery实现div右侧滑入滑出的效果
- jQuery实现div滑动效果
- jquery特效 - 网站水波纹
- 用css给div的border设置阴影
- 关于 jsdelivr
- 使用CSS提高网站性能的30种方法