OpenHarmony开发者论坛
标题:
开发者使用napi扩展TS接口时,常用的属性和实现接口的基本用法是什么?例如怎么获取env,怎么实现callback和promise,怎么使用libuv?
[打印本页]
作者:
北向实践与赋能
时间:
2024-1-4 10:59
标题:
开发者使用napi扩展TS接口时,常用的属性和实现接口的基本用法是什么?例如怎么获取env,怎么实现callback和promise,怎么使用libuv?
[md]开发者使用napi扩展TS接口时,常用的属性和实现接口的基本用法是什么?例如怎么获取env,怎么实现callback和promise,怎么使用libuv?
[/md]
作者:
北向实践与赋能
时间:
2024-1-4 10:59
标题:
开发者使用napi扩展TS接口时,常用的属性和实现接口的基本用法是什么?例如怎么获取env,怎么实现callback和promise,怎么使用libuv?
[md]**关键字**
napi
**解决方案**
1. env是使用napi的模块化编程,注册模块之后,调用回调的时候会通过回调函数调用过来:
```cpp
static napi_value CallNapi(napi_env env, napi_callback_info info)
{
size_t argc = 1;
napi_value object = nullptr;
napi_status status;
status = napi_get_cb_info(env, info, &argc, &object, nullptr, nullptr);
return object;
}
NAPI_MODULE_INIT() {
napi_property_descriptor desc[] = {
{ ""callNapi"", nullptr, CallNapi, nullptr, nullptr, nullptr, napi_default, nullptr }
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
```
2. callback实现:
```cpp
#include ""napi/native_api.h""
#include <assert.h>
static napi_value NativeCall(napi_env env, napi_callback_info info)
{
size_t argc = 1;
napi_value args[1] = { nullptr };
napi_status status;
status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
assert(status == napi_ok);
napi_valuetype valuetype;
napi_typeof(env, args[0], &valuetype);
if (valuetype != napi_valuetype::napi_function) {
napi_throw_type_error(env, nullptr, ""napi_function is expected"");
}
napi_value cb = args[0];
napi_value undefined;
status = napi_get_undefined(env, &undefined);
assert(status == napi_ok);
napi_value argv[2] = { nullptr };
status = napi_create_int32(env, 1, &argv[0]);
assert(status == napi_ok);
status = napi_create_int32(env, 2, &argv[1]);
assert(status == napi_ok);
napi_value result;
status = napi_call_function(env, undefined, cb, 2, argv, &result);
assert(status == napi_ok);
return nullptr;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {
{ ""nativeCall"", nullptr, NativeCall, nullptr, nullptr, nullptr, napi_default, nullptr }
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
static napi_module module = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = ""callback"",
.nm_priv = nullptr,
.reserved = { 0 },
};
extern ""C"" __attribute__((constructor)) void RegisterCallbackModule(void)
{
napi_module_register(&module);
}
```
3. promise实现参考:
```cpp
#include ""napi/native_api.h""
// Empty value so that macros here are able to return NULL or void
#define NAPI_RETVAL_NOTHING // Intentionally blank
#define GET_AND_THROW_LAST_ERROR(env) \
do { \
const napi_extended_error_info* errorInfo = nullptr; \
napi_get_last_error_info((env), &errorInfo); \
bool isPending = false; \
napi_is_exception_pending((env), &isPending); \
if (!isPending && errorInfo != nullptr) { \
const char* errorMessage = \
errorInfo->error_message != nullptr ? errorInfo->error_message : ""empty error message""; \
napi_throw_error((env), nullptr, errorMessage); \
} \
} while (0)
#define NAPI_ASSERT_BASE(env, assertion, message, retVal) \
do { \
if (!(assertion)) { \
napi_throw_error((env), nullptr, ""assertion ("" #assertion "") failed: "" message); \
return retVal; \
} \
} while (0)
#define NAPI_ASSERT(env, assertion, message) NAPI_ASSERT_BASE(env, assertion, message, nullptr)
#define NAPI_ASSERT_RETURN_VOID(env, assertion, message) \
NAPI_ASSERT_BASE(env, assertion, message, NAPI_RETVAL_NOTHING)
#define NAPI_CALL_BASE(env, theCall, retVal) \
do { \
if ((theCall) != napi_ok) { \
GET_AND_THROW_LAST_ERROR((env)); \
return retVal; \
} \
} while (0)
#define NAPI_CALL(env, theCall) NAPI_CALL_BASE(env, theCall, nullptr)
#define NAPI_CALL_RETURN_VOID(env, theCall) NAPI_CALL_BASE(env, theCall, NAPI_RETVAL_NOTHING)
struct AsyncData {
napi_deferred deferred;
napi_async_work work;
int32_t arg;
double retVal;
};
double DoSomething(int32_t val)
{
if (val != 0) {
return 1.0 / val;
}
return 0;
}
void ExecuteCallback(napi_env env, void* data)
{
AsyncData* asyncData = reinterpret_cast<AsyncData*>(data);
asyncData->retVal = DoSomething(asyncData->arg);
}
void CompleteCallback(napi_env env, napi_status status, void* data)
{
AsyncData* asyncData = reinterpret_cast<AsyncData*>(data);
napi_value retVal;
if (asyncData->retVal == 0) {
NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, ""arg can't be zero"", NAPI_AUTO_LENGTH, &retVal));
NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncData->deferred, retVal));
} else {
NAPI_CALL_RETURN_VOID(env, napi_create_double(env, asyncData->retVal, &retVal));
NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncData->deferred, retVal));
}
NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, asyncData->work));
asyncData->work = nullptr;
asyncData->deferred = nullptr;
delete asyncData;
}
static napi_value NativeCall(napi_env env, napi_callback_info info)
{
size_t argc = 1;
napi_value args[1] = { nullptr };
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
int32_t arg;
NAPI_CALL(env, napi_get_value_int32(env, args[0], &arg));
// Create promise
napi_deferred deferred;
napi_value promise;
NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
AsyncData* data = new AsyncData;
data->deferred = deferred;
data->arg = arg;
napi_async_work work;
napi_value workName;
napi_create_string_utf8(env, ""promise"", NAPI_AUTO_LENGTH, &workName);
NAPI_CALL(env, napi_create_async_work(env, nullptr, workName,
ExecuteCallback, CompleteCallback, data, &work));
data->work = work;
NAPI_CALL(env, napi_queue_async_work(env, work));
return promise;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {
{ ""nativeCall"", nullptr, NativeCall, nullptr, nullptr, nullptr, napi_default, nullptr }
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = ""promise"",
.nm_priv = nullptr,
.reserved = { 0 },
};
extern ""C"" __attribute__((constructor)) void RegisterPromiseModule(void)
{
napi_module_register(&demoModule);
}
```
4. libuv使用:可以直接导入libuv三方库使用
[/md]
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/)
Powered by Discuz! X3.5