如何使用 Node-addon-API 实现 node-nan 回调
how to implement node-nan callback using node-addon-api
到目前为止,我只实现了同步node-addon-api方法,即JavaScript函数进行调用,工作完成,插件返回。当涉及到 v8、libuv 和 node 的内部工作原理时,我在知识上有很大的差距,所以请纠正任何明显的误解。
目标是在从 v8 调用C++垃圾回收回调时调用 JavaScript 回调。我最初只是从 v8 垃圾回收回调调用 JavaScript 回调,但在几次调用后最终得到了一个 segv。似乎只是在从 v8 回调调用时调用 JavaScript 存在一些问题(v8 文档回调不应该分配对象(。所以我环顾四周,找到了一个基于 Nan 的示例,该示例使用libuv
和 Nan 的AsyncResource
进行回调。以下方法适用于node-nan
:
NAN_GC_CALLBACK(afterGC) {
uint64_t et = uv_hrtime() - gcStartTime;
// other bookkeeping for GCData_t raw.
if (doCallbacks) {
uv_async_t* async = new uv_async_t;
GCData_t* data = new GCData_t;
*data = raw;
data->gcTime = et;
async->data = data;
uv_async_init(uv_default_loop(), async, asyncCB);
uv_async_send(async);
}
}
class GCResponseResource : public Nan::AsyncResource {
public:
GCResponseResource(Local<Function> callback_)
: Nan::AsyncResource("nan:gcstats.DeferredCallback") {
callback.Reset(callback_);
}
~GCResponseResource() {
callback.Reset();
}
Nan::Persistent<Function> callback;
};
static GCResponseResource* asyncResource;
static void closeCB(uv_handle_t *handle) {
delete handle;
}
static void asyncCB(uv_async_t *handle) {
Nan::HandleScope scope;
GCData_t* data = static_cast<GCData_t*>(handle->data);
Local<Object> obj = Nan::New<Object>();
Nan::Set(obj, Nan::New("gcCount").ToLocalChecked(),
Nan::New<Number>((data->gcCount));
Nan::Set(obj, Nan::New("gcTime").ToLocalChecked(),
Nan::New<Number>(data->gcTime));
Local<Object> counts = Nan::New<v8::Object>();
for (int i = 0; i < maxTypeCount; i++) {
if (data->typeCounts[i] != 0) {
Nan::Set(counts, i, Nan::New<Number>(data->typeCounts[i]));
}
}
Nan::Set(obj, Nan::New("gcTypeCounts").ToLocalChecked(), counts);
Local<Value> arguments[] = {obj};
Local<Function> callback = Nan::New(asyncResource->callback);
v8::Local<v8::Object> target = Nan::New<v8::Object>();
asyncResource->runInAsyncScope(target, callback, 1, arguments);
delete data;
uv_close((uv_handle_t*) handle, closeCB);
}
我的问题是我将如何使用节点插件 api 而不是 nan 来做到这一点?
我不清楚uv_async_init
、uv_async_send
等的节点插件 API 等。这部分是因为我不清楚需要哪些底层N-API
(而不是node-addon-api
(函数。
我一直找不到这样的例子。回调示例是完全同步的。异步 pi 示例使用工作线程来执行任务,但与使用uv
基元的基于 nan 的代码中的方法相比,这似乎有点矫枉过正。
您的示例并不是真正的异步,因为 GC 回调在主线程中运行。但是,当 JS 世界因 GC 而停止时,这并不意味着它以允许回调运行的方式停止 - 因为 GC 可以在函数中间停止它。
您需要一个ThreadSafeFunction
才能执行此操作。看这里的例子: https://github.com/nodejs/node-addon-api/blob/main/doc/threadsafe_function.md
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- 如何在C++中使用非静态成员函数作为回调函数
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 用于在回调中调用解析器的设计模式
- 如何使用C++对象的成员函数作为 C 样式回调?
- Java从C++回调到C++回调
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 从不同的 cpp 调用回调函数会导致bad_function_call
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 不带轮询的 SDL2 事件回调
- C++存储带有可变参数的回调
- 如何使用 Node-addon-API 实现 node-nan 回调
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 调用某个回调函数两次会导致分段错误:Nan
- node.js Nan:在函数C++调用 JavaScript 回调
- 插件中节点.js/Nan 回调C++不频繁的隔离错误
- NodeJS Addon从NAN AsyncWorker::Execute内部调用Javascript回调
- 在c++11中,类似于node.js/javascript回调的线程