From 5f5cdfd33a24391e46a167072beaf3e8545e3a36 Mon Sep 17 00:00:00 2001 From: zhangmenghan Date: Mon, 28 Oct 2024 16:35:23 +0800 Subject: [PATCH 1/5] Wrap Signed-off-by: zhangmenghan --- .../src/main/cpp/include/javascriptapi.h | 2 +- .../napitutorials/entry/src/main/cpp/init.cpp | 5 +- .../javascriptapi/jsobjectwrap/napiwrap.cpp | 145 ++++++++++++------ .../src/main/cpp/types/libentry/index.d.ts | 6 +- .../javascript/jsobjectwrap/napiwrap.ets | 11 +- .../test/javascriptapi/jsobjectwrap.test.ets | 26 +++- 6 files changed, 136 insertions(+), 59 deletions(-) diff --git a/examples/napitutorials/entry/src/main/cpp/include/javascriptapi.h b/examples/napitutorials/entry/src/main/cpp/include/javascriptapi.h index e784305b..da06e27d 100644 --- a/examples/napitutorials/entry/src/main/cpp/include/javascriptapi.h +++ b/examples/napitutorials/entry/src/main/cpp/include/javascriptapi.h @@ -65,6 +65,6 @@ napi_value testNapiCreateFunction(napi_env env, napi_callback_info info); napi_value jsObjectWrapInit(napi_env env, napi_value exports); napi_value testNapiWrap(napi_env env, napi_callback_info info); -napi_value testNapiUnwrap(napi_env env, napi_callback_info info); +napi_value WrapInit(napi_env env, napi_value exports); #endif //NAPITUTORIALS_JAVASCRIPTAPI_H diff --git a/examples/napitutorials/entry/src/main/cpp/init.cpp b/examples/napitutorials/entry/src/main/cpp/init.cpp index 16649b4a..a37f883b 100644 --- a/examples/napitutorials/entry/src/main/cpp/init.cpp +++ b/examples/napitutorials/entry/src/main/cpp/init.cpp @@ -119,7 +119,10 @@ static napi_value Init(napi_env env, napi_value exports) // 对应 javascriptapi/jsobjectwrap/jsObjectWrapInit.cpp jsObjectWrapInit(env, exports); - + + // 对应 javascriptapi/jsobjectwrap/napiwrap.cpp + WrapInit(env, exports); + napi_property_descriptor descArr[] = { {"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr}, {"getTestCase", nullptr, getTestCase, nullptr, nullptr, nullptr, napi_default, nullptr}, diff --git a/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/napiwrap.cpp b/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/napiwrap.cpp index fca853d2..13fb3759 100644 --- a/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/napiwrap.cpp +++ b/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/napiwrap.cpp @@ -17,58 +17,105 @@ #include "javascriptapi.h" static const char *TAG = "[javascriptapi_object_wrap]"; -static const int MAX_BUFFER_SIZE = 128; -class Node { +class testNapiWrap { public: - Node(napi_env env, napi_value id) - { - // 将 JavaScript 字符串转换为 C++ 字符串 - size_t idLength = MAX_BUFFER_SIZE; - char buf[MAX_BUFFER_SIZE]; - char *buffer = buf; - napi_get_value_string_utf8(env, id, buffer, idLength, nullptr); - // 将 C++ 字符串转换为 std::string - _id = std::string(buffer); - } - std::string GetId() { return _id; } + static napi_value Init(napi_env env, napi_value exports); + static void Destructor(napi_env env, void *nativeObject, void *finalize_hint); + private: - std::string _id; // 成员变量,存储 id + explicit testNapiWrap(napi_value value_ = 0); + ~testNapiWrap(); + + static napi_value New(napi_env env, napi_callback_info info); + static napi_value Tyof(napi_env env, napi_callback_info info); + + napi_value value_; + napi_env env_; + napi_ref wrapper_; }; -napi_value testNapiWrap(napi_env env, napi_callback_info info) -{ - size_t argc = PARAM1; - napi_value argv[PARAM1] = {0}; - napi_value thisObj = nullptr; - void *data = nullptr; - napi_status status; - napi_value cons; - const napi_extended_error_info *extended_error_info; - // 获取回调函数的参数信息 - status = napi_get_cb_info(env, info, &argc, argv, &thisObj, &data); - if (status != napi_ok) { - getErrMsg(status, env, extended_error_info, "Failed to get callback info", TAG); - return NULL; - } - napi_valuetype resultType; - napi_typeof(env, argv[PARAM0], &resultType); - if (resultType != napi_string) { - std::string res = "Expected a string, got " + std::to_string(resultType); - napi_throw_error(env, NULL, res.c_str()); - return NULL; - } - auto instance = new Node(env, argv[PARAM0]); - status = napi_wrap(env, thisObj, instance, - [](napi_env environment, void *data, void *hint) { - auto objInfo = reinterpret_cast(data); - if (objInfo != nullptr) { - delete objInfo; - } - }, NULL, NULL); - if (status != napi_ok) { - getErrMsg(status, env, extended_error_info, "wrap", TAG); - return NULL; - } - return thisObj; +static thread_local napi_ref g_ref = nullptr; + +testNapiWrap::testNapiWrap(napi_value value) : value_(value), env_(nullptr), wrapper_(nullptr) {} + +testNapiWrap::~testNapiWrap() { napi_delete_reference(env_, wrapper_); } + +void testNapiWrap::Destructor(napi_env env, void *nativeObject, [[maybe_unused]] void *finalize_hint) { + reinterpret_cast(nativeObject)->~testNapiWrap(); +} + +napi_value testNapiWrap::Tyof(napi_env env, napi_callback_info info) { + napi_value jsThis; + napi_valuetype result; + napi_value resultStr; + napi_status status; + size_t argc = PARAM1; + napi_value argv[PARAM1]; + const napi_extended_error_info *extended_error_info; + status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr); + if (status != napi_ok) { + getErrMsg(status, env, extended_error_info, "get cb info", TAG); + return NULL; + } + testNapiWrap *obj; + status = napi_unwrap(env, jsThis, reinterpret_cast(&obj)); + if (status != napi_ok || obj == nullptr) { + getErrMsg(status, env, extended_error_info, "call napi_typeof()", TAG); + return NULL; + } + status = napi_typeof(env, argv[0], &result); + if (status != napi_ok) { + getErrMsg(status, env, extended_error_info, "call napi_typeof()", TAG); + return NULL; + } + status = napiValueType2Str(env, result, &resultStr); + if (status != napi_ok) { + std::string errMsg = "Failed to convert napi_valuetype " + std::to_string(status) + " to string"; + napi_throw_error(env, NULL, errMsg.c_str()); + return NULL; + } + return resultStr; +} + +napi_value testNapiWrap::New(napi_env env, napi_callback_info info) { + napi_value newTarget; + napi_get_new_target(env, info, &newTarget); + if (newTarget != nullptr) { + size_t argc = PARAM1; + napi_value args[PARAM1]; + napi_value jsThis; + napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr); + napi_value value; + testNapiWrap *obj = new testNapiWrap(value); + obj->env_ = env; + napi_wrap(env, jsThis, reinterpret_cast(obj), testNapiWrap::Destructor, + nullptr, // finalize_hint + &obj->wrapper_); + return jsThis; + } else { + size_t argc = PARAM1; + napi_value args[PARAM1]; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_value cons; + napi_get_reference_value(env, g_ref, &cons); + napi_value instance; + napi_new_instance(env, cons, argc, args, &instance); + return instance; + } +} + +napi_value testNapiWrap::Init(napi_env env, napi_value exports) { + napi_property_descriptor properties[] = {{"Tyof", nullptr, Tyof, nullptr, nullptr, nullptr, napi_default, nullptr}}; + napi_value cons; + napi_define_class(env, "testNapiWrap", NAPI_AUTO_LENGTH, New, nullptr, 1, properties, &cons); + napi_create_reference(env, cons, 1, &g_ref); + napi_set_named_property(env, exports, "testNapiWrap", cons); + return exports; +} + + +napi_value WrapInit(napi_env env, napi_value exports) { + testNapiWrap::Init(env, exports); + return exports; } diff --git a/examples/napitutorials/entry/src/main/cpp/types/libentry/index.d.ts b/examples/napitutorials/entry/src/main/cpp/types/libentry/index.d.ts index a200f48e..f492c8a3 100644 --- a/examples/napitutorials/entry/src/main/cpp/types/libentry/index.d.ts +++ b/examples/napitutorials/entry/src/main/cpp/types/libentry/index.d.ts @@ -25,6 +25,11 @@ export interface Callback { (data: T): void; } +export class testNapiWrap { + constructor(); + Tyof: (arg: any) => string; +} + export const add: (a: number, b: number) => number; export const getTestCase: (a: number) => tcBase; export const testNapiStatus: (a: number, b: number) => number; @@ -71,5 +76,4 @@ export const testNapiCallFunction: (a: Function, b: number) => number; export const testNapiCreateFunction: () => any; /* work_with_javascript_objectwrap */ -export const testNapiWrap: (a: string) => any; export const testNapiUnwrap: (a: any) => string; \ No newline at end of file diff --git a/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets b/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets index c4c7146d..5e795f64 100644 --- a/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets +++ b/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets @@ -16,12 +16,16 @@ import router from '@ohos.router'; import image from '@ohos.multimedia.image'; import Logger from '../../../util/Logger'; -import testNapi, { testNapiValue } from 'libentry.so'; +import testNapi from 'libentry.so'; import { TitleBar } from '../../../common/TitleBar' import hilog from '@ohos.hilog'; const TAG: string = 'napi_wrap'; +interface Cafee { + name: string; +} + @Entry @Component struct napiwrap { @@ -83,8 +87,9 @@ struct napiwrap { .margin({ left: 24 }) .id('napi_wrap') .onClick(() => { - console.log(`testNapi.testNapiWrap() is ${testNapi.testNapiWrap('tree')}`); - this.testcont = this.testcont.replace('log(result)', 'log(## ' +typeof (testNapi.testNapiWrap('tree')) + ' ##)'); + let node: testNapi.testNapiWrap = new testNapi.testNapiWrap(); + console.log(`Node.Tyof('1024') is ${node.Tyof(1024)}`); + this.testcont = this.testcont.replace('log(result)', 'log(## type of node is ' + typeof (node) + ' ##)'); }) } .width('100%') diff --git a/examples/napitutorials/entry/src/ohosTest/ets/test/javascriptapi/jsobjectwrap.test.ets b/examples/napitutorials/entry/src/ohosTest/ets/test/javascriptapi/jsobjectwrap.test.ets index d88edb75..5bdb6eff 100644 --- a/examples/napitutorials/entry/src/ohosTest/ets/test/javascriptapi/jsobjectwrap.test.ets +++ b/examples/napitutorials/entry/src/ohosTest/ets/test/javascriptapi/jsobjectwrap.test.ets @@ -42,11 +42,29 @@ export default function abilityTestJsObjectWrap() { it('testNapiWrap', 0, () => { // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. hilog.info(0x0000, 'testTag', '%{public}s', 'it testNapiWrap begin'); - hilog.info(0x0000, 'testTag', `type of napi_wrap("7") is = ${typeof (testNapi.testNapiWrap("7"))}`); - expect(typeof (testNapi.testNapiWrap("7"))).assertEqual('object'); + let ret: testNapi.testNapiWrap = new testNapi.testNapiWrap(); + hilog.info(0x0000, 'testTag', `type of napi_wrap() is = ${typeof (ret)}`); + expect(typeof (ret)).assertEqual('object'); + let ret1 = ret.Tyof(''); + hilog.info(0x0000, 'testTag', `type of ret.Tyof('') is = ${typeof (ret1)}`); + expect(ret1).assertEqual('string'); - hilog.info(0x0000, 'testTag', `type of napi_wrap("tree") is = ${typeof (testNapi.testNapiWrap("tree"))}`); - expect(typeof (testNapi.testNapiWrap("tree"))).assertEqual('object'); + + let ret2 = ret.Tyof(false); + hilog.info(0x0000, 'testTag', `type of ret.Tyof(false) is = ${typeof (ret2)}`); + expect(ret2).assertEqual('boolean'); + + let ret3 = ret.Tyof(3); + hilog.info(0x0000, 'testTag', `type of ret.Tyof(3) is = ${typeof (ret3)}`); + expect(ret3).assertEqual('number'); + + let ret4 = ret.Tyof(null); + hilog.info(0x0000, 'testTag', `type of ret.Tyof(null) is = ${typeof (ret4)}`); + expect(ret4).assertEqual('null'); + + let ret5 = ret.Tyof(undefined); + hilog.info(0x0000, 'testTag', `type of ret.Tyof(3) is = ${typeof (ret5)}`); + expect(ret5).assertEqual('undefined'); }) it('testNapiUnwrap', 0, () => { From 29f1a4b82548b6ca5ed5e5f8f939600ac4f254ff Mon Sep 17 00:00:00 2001 From: zhangmenghan Date: Mon, 28 Oct 2024 17:06:39 +0800 Subject: [PATCH 2/5] modified Signed-off-by: zhangmenghan --- .../cpp/javascriptapi/jsobjectwrap/napiwrap.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/napiwrap.cpp b/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/napiwrap.cpp index 13fb3759..0b639d92 100644 --- a/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/napiwrap.cpp +++ b/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/napiwrap.cpp @@ -21,7 +21,7 @@ static const char *TAG = "[javascriptapi_object_wrap]"; class testNapiWrap { public: static napi_value Init(napi_env env, napi_value exports); - static void Destructor(napi_env env, void *nativeObject, void *finalize_hint); + static void Destructor(napi_env env, void *nativeObject, void *finalizeHint); private: explicit testNapiWrap(napi_value value_ = 0); @@ -41,11 +41,13 @@ testNapiWrap::testNapiWrap(napi_value value) : value_(value), env_(nullptr), wra testNapiWrap::~testNapiWrap() { napi_delete_reference(env_, wrapper_); } -void testNapiWrap::Destructor(napi_env env, void *nativeObject, [[maybe_unused]] void *finalize_hint) { +void testNapiWrap::Destructor(napi_env env, void *nativeObject, [[maybe_unused]] void *finalizeHint) +{ reinterpret_cast(nativeObject)->~testNapiWrap(); } -napi_value testNapiWrap::Tyof(napi_env env, napi_callback_info info) { +napi_value testNapiWrap::Tyof(napi_env env, napi_callback_info info) +{ napi_value jsThis; napi_valuetype result; napi_value resultStr; @@ -78,7 +80,8 @@ napi_value testNapiWrap::Tyof(napi_env env, napi_callback_info info) { return resultStr; } -napi_value testNapiWrap::New(napi_env env, napi_callback_info info) { +napi_value testNapiWrap::New(napi_env env, napi_callback_info info) +{ napi_value newTarget; napi_get_new_target(env, info, &newTarget); if (newTarget != nullptr) { @@ -105,7 +108,8 @@ napi_value testNapiWrap::New(napi_env env, napi_callback_info info) { } } -napi_value testNapiWrap::Init(napi_env env, napi_value exports) { +napi_value testNapiWrap::Init(napi_env env, napi_value exports) +{ napi_property_descriptor properties[] = {{"Tyof", nullptr, Tyof, nullptr, nullptr, nullptr, napi_default, nullptr}}; napi_value cons; napi_define_class(env, "testNapiWrap", NAPI_AUTO_LENGTH, New, nullptr, 1, properties, &cons); @@ -115,7 +119,8 @@ napi_value testNapiWrap::Init(napi_env env, napi_value exports) { } -napi_value WrapInit(napi_env env, napi_value exports) { +napi_value WrapInit(napi_env env, napi_value exports) +{ testNapiWrap::Init(env, exports); return exports; } From c2ae3ad5e8335ab93f85fe8e172772b027744dff Mon Sep 17 00:00:00 2001 From: zhangmenghan Date: Mon, 28 Oct 2024 17:15:04 +0800 Subject: [PATCH 3/5] modified Signed-off-by: zhangmenghan --- .../napitutorials/entry/src/main/cpp/include/javascriptapi.h | 2 +- .../main/cpp/javascriptapi/jsobjectwrap/jsObjectWrapInit.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/napitutorials/entry/src/main/cpp/include/javascriptapi.h b/examples/napitutorials/entry/src/main/cpp/include/javascriptapi.h index da06e27d..7771597c 100644 --- a/examples/napitutorials/entry/src/main/cpp/include/javascriptapi.h +++ b/examples/napitutorials/entry/src/main/cpp/include/javascriptapi.h @@ -64,7 +64,7 @@ napi_value SayHello(napi_env env, napi_callback_info info); napi_value testNapiCreateFunction(napi_env env, napi_callback_info info); napi_value jsObjectWrapInit(napi_env env, napi_value exports); -napi_value testNapiWrap(napi_env env, napi_callback_info info); +napi_value testNapiUnwrap(napi_env env, napi_callback_info info); napi_value WrapInit(napi_env env, napi_value exports); #endif //NAPITUTORIALS_JAVASCRIPTAPI_H diff --git a/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/jsObjectWrapInit.cpp b/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/jsObjectWrapInit.cpp index 61e3a01f..20705e38 100644 --- a/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/jsObjectWrapInit.cpp +++ b/examples/napitutorials/entry/src/main/cpp/javascriptapi/jsobjectwrap/jsObjectWrapInit.cpp @@ -19,7 +19,6 @@ napi_value jsObjectWrapInit(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { - {"testNapiWrap", nullptr, testNapiWrap, nullptr, nullptr, nullptr, napi_default, nullptr}, {"testNapiUnwrap", nullptr, testNapiUnwrap, nullptr, nullptr, nullptr, napi_default, nullptr}}; napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc); From 9cbaf734402180c454709e4530b692ea8ffc2e70 Mon Sep 17 00:00:00 2001 From: zhangmenghan Date: Mon, 28 Oct 2024 17:18:37 +0800 Subject: [PATCH 4/5] examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets Signed-off-by: zhangmenghan --- .../src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets b/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets index 5e795f64..1ed3e81c 100644 --- a/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets +++ b/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets @@ -22,10 +22,6 @@ import hilog from '@ohos.hilog'; const TAG: string = 'napi_wrap'; -interface Cafee { - name: string; -} - @Entry @Component struct napiwrap { From 90e11e98a5118d2dbd6b281e7acda04b04887e35 Mon Sep 17 00:00:00 2001 From: zhangmenghan Date: Mon, 28 Oct 2024 17:33:10 +0800 Subject: [PATCH 5/5] modified Signed-off-by: zhangmenghan --- .../src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets | 5 ++++- .../ohosTest/ets/test/javascriptapi/jsobjectwrap.test.ets | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets b/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets index 1ed3e81c..7a22b075 100644 --- a/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets +++ b/examples/napitutorials/entry/src/main/ets/pages/javascript/jsobjectwrap/napiwrap.ets @@ -33,6 +33,8 @@ struct napiwrap { @State testcont: string = ' // 测试 N-API napi_wrap \n' + ' const result = testNapi.testNapiWrap(); \n' + ' console.log(result); \n' + + ' const ret = result.Tyof(1024); \n' + + ' console.log(ret);\n' controller: TextAreaController = new TextAreaController() @@ -84,8 +86,9 @@ struct napiwrap { .id('napi_wrap') .onClick(() => { let node: testNapi.testNapiWrap = new testNapi.testNapiWrap(); - console.log(`Node.Tyof('1024') is ${node.Tyof(1024)}`); + let ret = node.Tyof(1024); this.testcont = this.testcont.replace('log(result)', 'log(## type of node is ' + typeof (node) + ' ##)'); + this.testcont = this.testcont.replace('log(ret)', 'log(## ' + ret + ' ##)'); }) } .width('100%') diff --git a/examples/napitutorials/entry/src/ohosTest/ets/test/javascriptapi/jsobjectwrap.test.ets b/examples/napitutorials/entry/src/ohosTest/ets/test/javascriptapi/jsobjectwrap.test.ets index 5bdb6eff..5eb708a3 100644 --- a/examples/napitutorials/entry/src/ohosTest/ets/test/javascriptapi/jsobjectwrap.test.ets +++ b/examples/napitutorials/entry/src/ohosTest/ets/test/javascriptapi/jsobjectwrap.test.ets @@ -45,11 +45,11 @@ export default function abilityTestJsObjectWrap() { let ret: testNapi.testNapiWrap = new testNapi.testNapiWrap(); hilog.info(0x0000, 'testTag', `type of napi_wrap() is = ${typeof (ret)}`); expect(typeof (ret)).assertEqual('object'); + let ret1 = ret.Tyof(''); hilog.info(0x0000, 'testTag', `type of ret.Tyof('') is = ${typeof (ret1)}`); expect(ret1).assertEqual('string'); - let ret2 = ret.Tyof(false); hilog.info(0x0000, 'testTag', `type of ret.Tyof(false) is = ${typeof (ret2)}`); expect(ret2).assertEqual('boolean');