NAPI 類對(duì)象導(dǎo)出及其生命周期管理(下)

??想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??
??51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)??
一、樣例工程源碼剖析
- 工程的模板是Native C++,模型是Stage。
- 源碼剖析主要圍繞以下幾個(gè)文件。
1、NAPI導(dǎo)出對(duì)象和生命周期管理具體實(shí)現(xiàn)
(1)定義NapiTest類及方法
- Napi.h文件內(nèi)容如下:
napi_value
- Node.js Node-API的值用napi_value類型表示。
OpenHarmony NAPI將ECMAScript標(biāo)準(zhǔn)中定義的Boolean、Null、Undefined、Number、BigInt、String、Symbol和Object八種數(shù)據(jù)類型,以及函數(shù)對(duì)應(yīng)的Function類型,統(tǒng)一封裝成napi_value類型,下文中表述為JS類型,用于接收ArkUI應(yīng)用傳遞過(guò)來(lái)的數(shù)據(jù)及返回?cái)?shù)據(jù)給ArkUI應(yīng)用。 - 這是一個(gè)不透明的指針,用于表示JavaScript值。
napi_ref
- 這是用來(lái)引用napi_value的抽象。這允許用戶管理JavaScript值的生命周期,包括顯式地定義它們的最小生命周期。
https://nodejs.org/docs/latest-v14.x/api/n-api.html#n_api_napi_ref
napi_env
- napi_env用于表示上下文,底層的Node-API實(shí)現(xiàn)可以使用該上下文持久保持VM-specific的狀態(tài)。
https://nodejs.org/docs/latest-v14.x/api/n-api.html#n_api_napi_env
(2)將NapiTest類定義為js類
在定義js類之前,需要先設(shè)置js類對(duì)外導(dǎo)出的方法
napi_property_descriptor
參考 https://nodejs.org/docs/latest-v14.x/api/n-api.html#n_api_napi_property_descriptor。
Node.js Node-API有一組API來(lái)獲取和設(shè)置JavaScript對(duì)象的屬性。在JavaScript中,屬性被表示為一個(gè)鍵和一個(gè)值的元組?;旧?,Node-API中的所有屬性鍵都可以用以下形式中的任一一種表示:
- Named:一個(gè)簡(jiǎn)單的UTF-8編碼的字符串。
- Integer-Indexed:索引值,由uint32_t表示。
- JavaScript value:在Node-API中通過(guò)napi_value表示。它可以是一個(gè)napi_value,表示字符串、數(shù)字或符號(hào)。
參數(shù)解析:
- utf8name:在定義js類之前設(shè)置的js類對(duì)外導(dǎo)出的方法名字,編碼為UTF8。必須為該屬性提供utf8name或name中的一個(gè)。(utf8name和name其中一個(gè)必須是NULL)。
- name:可選的napi_value,指向一個(gè)JavaScript字符串或符號(hào),用作屬性的鍵。必須為該屬性提供utf8name或name中的一個(gè)。
- method:將屬性描述符對(duì)象的value屬性設(shè)置為method表示的JavaScript函數(shù)。如果傳入這個(gè)參數(shù),將value、getter和setter設(shè)置為NULL(因?yàn)檫@些成員不會(huì)被使用)。
- attributes:與特定屬性相關(guān)聯(lián)的屬性。
- data:調(diào)用函數(shù)時(shí)傳遞給method、getter和setter的callback data。
定義與C++類相對(duì)應(yīng)的JavaScript類
napi_define_class
napi_define_class函數(shù)說(shuō)明:
https://nodejs.org/docs/latest-v14.x/api/n-api.html#n_api_napi_define_class
功能:定義與C ++ 類相對(duì)應(yīng)的JavaScript類。
參數(shù)說(shuō)明:
- [in] env: 調(diào)用api的環(huán)境。
- [in] utf8name: C ++ 類的名稱。
- [in] length: C ++ 類的名稱的長(zhǎng)度,默認(rèn)自動(dòng)長(zhǎng)度使用NAPI_AUTO_LENGTH。
- [in] constructor: 處理C ++ 類實(shí)例構(gòu)造的回調(diào)函數(shù) (因?yàn)镃onstructor函數(shù)被napi_define_class調(diào)用了)。在導(dǎo)出C ++ 類對(duì)象時(shí),這個(gè)函數(shù)必須是帶有napi_callback簽名(Constructor函數(shù)有napi_callback簽名是指要滿足typedef napi_value (*napi_callback)(napi_env, napi_callback_info);的形式)的靜態(tài)成員。不能使用c ++ 的類構(gòu)造函數(shù)。
- [in] data: 作為回調(diào)信息的數(shù)據(jù)屬性傳遞給構(gòu)造函數(shù)回調(diào)的可選數(shù)據(jù)。
- [in] property_count: 屬性數(shù)組中參數(shù)的個(gè)數(shù)。
- [in] properties: 屬性數(shù)組,具體看代碼中napi_property_descriptor部分。
- [out] result: 通過(guò)類構(gòu)造函數(shù)綁定類實(shí)例的napi_value對(duì)象。
返回:如果API調(diào)用成功返回napi_ok。
JS構(gòu)造函數(shù)。
如果一個(gè)js函數(shù)被使用new操作符來(lái)調(diào)用了,那么這個(gè)函數(shù)就稱之為js構(gòu)造函數(shù)C++類回調(diào)函數(shù)我們調(diào)用別人的API叫call,調(diào)用的第三方API調(diào)用我們的函數(shù)叫回調(diào)(callback)

實(shí)現(xiàn)js類的構(gòu)造函數(shù)
當(dāng)ArkTS應(yīng)用在js端通過(guò)new方法獲取類對(duì)象的時(shí)候,此時(shí)會(huì)調(diào)用 napi_define_class 中設(shè)置的 constructor 回調(diào)函數(shù),該函數(shù)實(shí)現(xiàn)方法如下:
- NapiTest::Destructo方法是用來(lái)釋放創(chuàng)建的對(duì)象:
napi_wrap
功能:將C++類實(shí)例綁定到j(luò)s對(duì)象,并關(guān)聯(lián)對(duì)應(yīng)的生命周期
參數(shù)說(shuō)明:
- [in] env: 調(diào)用api的環(huán)境。
- [in] js_object: 綁定native_object的js對(duì)象。
- [in] native_object: C++類實(shí)例對(duì)象。
- [in] finalize_cb: 釋放實(shí)例對(duì)象的回調(diào)函數(shù)。
- [in] finalize_hint: 傳遞給回調(diào)函數(shù)的數(shù)據(jù)。
- [out] result: 綁定js對(duì)象的引用。
返回:調(diào)用成功返回0,失敗返回其他。
napi_get_cb_info
NAPI提供了napi_get_cb_info()方法可從napi_callback_info中獲取參數(shù)列表、this及其他數(shù)據(jù)。這個(gè)方法在constructor回調(diào)函數(shù)中使用,從給定的回調(diào)信息中檢索有關(guān)調(diào)用的詳細(xì)信息,如參數(shù)和This指針。
參數(shù)說(shuō)明:
- [in] env: 傳入接口調(diào)用者的環(huán)境,包含js引擎等,由框架提供,默認(rèn)情況下直接傳入即可。
- [in] cbinfo: napi_callback_info對(duì)象,上下文的信息。
- [in-out] argc: argv數(shù)組的長(zhǎng)度。若napi_callback_info中實(shí)際包含的參數(shù)的個(gè)數(shù)大于請(qǐng)求的數(shù)量argc,將只復(fù)制argc的值所指定數(shù)量的參數(shù)只argv中。若實(shí)際的參數(shù)個(gè)數(shù)小于請(qǐng)求的數(shù)量,將復(fù)制全部的參數(shù),數(shù)組多余的空間用空值填充,并將參數(shù)實(shí)際長(zhǎng)度寫(xiě)入argc。
- [out] argv: 用于接收參數(shù)列表。
- [out] this_arg: 用于接收this對(duì)象。
- [out] data: NAPI的上下文數(shù)據(jù) 返回值:返回napi_ok表示轉(zhuǎn)換成功,其他值失敗。下面的返回napi_status方法一樣。
(3)導(dǎo)出js類
在設(shè)置js類導(dǎo)出前,需要先創(chuàng)建生命周期
- constructor 定義js類時(shí)返回的代表類的構(gòu)造函數(shù)的數(shù)據(jù)。
- sConstructor_ 生命周期變量。
napi_create_reference
napi_create_reference為對(duì)象創(chuàng)建一個(gè)reference,以延長(zhǎng)其生命周期。調(diào)用者需要自己管理reference生命周期。
napi_create_reference函數(shù)說(shuō)明:
功能:通過(guò)引用對(duì)象創(chuàng)建新的生命周期引用對(duì)象。
- [in] env: 調(diào)用 API 的環(huán)境。
- [in] value: napi_value表示我們要引用的對(duì)象。
- [in] initial_refcount: 生命周期變量的初始引用計(jì)數(shù)。
- [out] result: 新建的生命周期引用對(duì)象。
返回 napi_ok 這個(gè)API就是成功的。
將生命周期變量作為導(dǎo)出對(duì)象的傳入屬性,并將js類導(dǎo)出到exports中
napi_set_named_property
為給定對(duì)象的屬性設(shè)置一個(gè)名稱。
- [in] env: 調(diào)用API的環(huán)境。
- [in] object: NapiTest對(duì)象相關(guān)屬性要綁定的屬性值。
- [in] utf8Name: js類的名稱。
- [in] value: 要引用的對(duì)象。
返回 napi_ok 則這個(gè)API是成功的。
設(shè)置導(dǎo)出對(duì)象的屬性
hello.cpp中:
napi_define_properties
https://nodejs.org/docs/latest-v14.x/api/n-api.html#n_api_napi_define_properties。
作用:批量的向給定Object中定義屬性。
- [in] env: 調(diào)用api的環(huán)境。
- [in] object: js對(duì)象相關(guān)屬性的導(dǎo)出變量。
- [in] property_count: 屬性數(shù)組中的元素?cái)?shù)。
- [in] properties: 屬性數(shù)組。
(4)創(chuàng)建類的實(shí)例對(duì)象
- ArkTS應(yīng)用除了調(diào)用new方法獲取類的實(shí)例外,我們也可以提供一些方法讓ArkTS應(yīng)用獲取對(duì)應(yīng)的類的實(shí)例,如在我們的NapiTest類中,定義了一個(gè)Create方法,該方法實(shí)現(xiàn)了NapiTest類實(shí)例的獲取。具體實(shí)現(xiàn)如下:
- 在napi接口的注冊(cè)中將該方法以接口的方式導(dǎo)出,應(yīng)用層就可以直接調(diào)用該接口并獲取到該類的實(shí)例對(duì)。特別說(shuō)明:如果單獨(dú)實(shí)現(xiàn)了一個(gè)類實(shí)例獲取的方法,那么js的類構(gòu)造函數(shù)可以不實(shí)現(xiàn)(也就是定義js結(jié)構(gòu)體時(shí)實(shí)際的構(gòu)建函數(shù)Constructor及釋放資源的函數(shù)Destructor的代碼夠可以不寫(xiě))。
napi_get_reference_value
https://nodejs.org/docs/latest-v14.x/api/n-api.html#n_api_napi_get_reference_value。
函數(shù)說(shuō)明:
- 作用:獲取與reference相關(guān)聯(lián)的js對(duì)象
- [in] env: 調(diào)用API的環(huán)境
- [in] ref: 生命周期管理的變量
- [out] result: 對(duì)象引用的reference.
napi_new_instance
https://nodejs.org/docs/latest-v14.x/api/n-api.html#n_api_napi_new_instance。
- 作用:通過(guò)給定的構(gòu)造函數(shù),構(gòu)建一個(gè)對(duì)象。
- [in] env: 調(diào)用API的環(huán)境。
- [in] cons: napi_value表示要作為構(gòu)造函數(shù)調(diào)用的 JavaScript 函數(shù)。
- [in] argc: argv 數(shù)組中的元素計(jì)數(shù)。
- [in] argv: JavaScript 值數(shù)組,表示構(gòu)造函數(shù)的參數(shù)napi_value。
- [out] result: napi_value表示返回的 JavaScript 對(duì)象。
2、 index.d.ts聲明文件編寫(xiě)
使用NAPI框架代碼生成工具,可以根據(jù).h生成.d.ts
?https://gitee.com/openharmony/napi_generator/blob/master/docs/INSTRUCTION_ZH.md。
也可以寫(xiě)成:
3、CMakeLists.txt文件
4、index.ets文件
知識(shí)點(diǎn)附送
napi接口名稱
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/native-lib/third_party_napi/napi.md
文章相關(guān)附件可以點(diǎn)擊下面的原文鏈接前往下載:
?? https://ost.51cto.com/resource/2579??
??想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??























