NAPI(Native API)是OpenHarmony系統(tǒng)中的一套原生模塊擴(kuò)展開發(fā)框架,它基于Node.js N-API規(guī)范開發(fā),為開發(fā)者提供了JavaScript與C/C++模塊之間相互調(diào)用的交互能力。可以在NodeJs官網(wǎng)查看各種NAPI接口定義說明。
NAPI作用
- OpenHarmony系統(tǒng)可以將框架層豐富的模塊功能通過js接口開放給上層應(yīng)用使用
- 上層應(yīng)用也可以將一些對性能有要求或者需要調(diào)用到系統(tǒng)側(cè)框架的功能使用C/C++封裝實(shí)現(xiàn),下探到系統(tǒng)層以提高運(yùn)行效率
NAPI在系統(tǒng)中的位置
NAPI在OpenHarmony中屬于ArkUI框架的一部分。
NAIP框架代碼在 foundationarkuinapi 路徑下。總體上可分為interface、native_engine 和 xxxManager 三部分。
interface 目錄為NAPI開發(fā)者提供了各種常用功能的API接口及宏定義。
native_engine 目錄是NAPI框架的核心部分,interface目錄提供的接口對應(yīng)的功能都在這里實(shí)現(xiàn)。C++與Js之間的調(diào)用交互最終是要依托JS引擎來完成的,針對系統(tǒng)支持的不同JS引擎,在impl目錄中也有對應(yīng)的4種實(shí)現(xiàn)(ark, jerryscript, quickjs, v8)。
此外,還有幾個Manager目錄,分別負(fù)責(zé)模塊注冊、引用對象管理、作用域管理等專項(xiàng)功能。
NAPI使用
假設(shè)我們在框架測使用c/c++實(shí)現(xiàn)了hello模塊,該模塊提供了一個接口int hello(const std::string &s),傳入一個字符串,打印該字符串。
要使用js調(diào)用到如上hello接口,需要解決如下幾個問題
- 模塊注冊(import的模塊名稱hello,是怎么對應(yīng)到實(shí)際的c++lib庫的?) — Module Manager。
- 方法名映射(js調(diào)用的hello方法,是怎么對應(yīng)到native的C/C++的方法的?) — Native Engine。
- 數(shù)據(jù)傳遞與轉(zhuǎn)換(js傳入的入?yún)?、得到的返回結(jié)果,需要轉(zhuǎn)換成C/C++代碼可以操作的數(shù)據(jù)類型)
c++方法具體實(shí)現(xiàn):
// hello.h
#ifndef HELLO_H
#define HELLO_H
#include < string >
namespace OHOS {
namespace hello {
int hello(const std::string &s);
} // namespace add
} // namespace OHOS
#endif // HELLO_H
// hello.cpp
#include < iostream >
#include "hello.h"
namespace OHOS {
namespace hello {
int hello(const std::string &s);
{
std::cout < < s < < endl;
return 0;
}
} // namespace add
} // namespace OHOS
此時需要為js提供調(diào)用,需要為該接口進(jìn)行NAPI封裝
// helloNapi.cpp
#include "napi/native_api.h"
#include "hello.h"
static napi_value Hello(napi_env env, napi_callback_info info)
{
// 根據(jù)環(huán)境變量獲取參數(shù)
// js參數(shù)個數(shù)
size_t argc = 1;
// 參數(shù)定義
napi_value argv[1] = { 0 };
// 入?yún)⒆兞揩@取
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
// 獲取入?yún)⒌念愋?/span>
napi_valuetype valueType = napi_undefined;
napi_typeof(env, argv[0], &valueType);
// js類型的入?yún)⒅缔D(zhuǎn)換為C/C++可以操作的數(shù)據(jù)類型
char value[VALUE_BUFFER_SIZE] = { 0 };
size_t valueLen = 0;
napi_get_value_string_utf8(env, argv[0], value, VALUE_BUFFER_SIZE, &valueLen);
std::string s = value;
// 調(diào)用hello接口
int ret = hello(s);
// C/C++數(shù)據(jù)類型轉(zhuǎn)換為JS數(shù)據(jù)類型并返回給應(yīng)用層
// JS字符串對象
napi_value result = nullptr;
retult = napi_create_int32(env, ret, &result);
//返回JS對象
return result;
}
// 方法名映射
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {
{ "hello", nullptr, Hello, nullptr, nullptr, nullptr, napi_default, nullptr }
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
// nm_modname為提供給應(yīng)用側(cè)調(diào)用的模塊名稱
static napi_module helloModule = {
.nm_version =1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "hello",
.nm_priv = ((void*)0),
.reserved = { 0 },
};
// 注冊模塊
extern "C" __attribute__((constructor)) void RegisterNative_helloModule(void)
{
napi_module_register(&helloModule);
}
編譯生成假設(shè)為hello.z.so
js調(diào)用代碼
// hello.ets
// 引入hello napi模塊
import testNapi from '@ohos.hello'
// 調(diào)用js接口 hello
testNapi.hello("hello world")
以上就是簡單的NAPI簡介以及簡單的一個NAPI應(yīng)用開發(fā)模版。更多鴻蒙開發(fā)內(nèi)容,前往主頁:
審核編輯 黃宇
-
鴻蒙
+關(guān)注
關(guān)注
57文章
2305瀏覽量
42696 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3646瀏覽量
16071
發(fā)布評論請先 登錄
相關(guān)推薦
評論