为了从多个 Node.js 环境加载,例如主线程和工作线程,插件还需要:

    • 是一个 N-API 插件,或
    • 如上所述,使用 NODE_MODULE_INIT() 声明为上下文感知。

    为了支持 [Worker] 线程,插件需要清理可能分配的任何资源(当存在这样的线程时)。 这可以通过使用 AddEnvironmentCleanupHook() 函数来实现:

    1. void AddEnvironmentCleanupHook(v8::Isolate* isolate,
    2. void (*fun)(void* arg),
    3. void* arg);

    此函数添加了一个钩子,该钩子将在给定的 Node.js 实例关闭之前运行。 如有必要,可以在运行之前使用 RemoveEnvironmentCleanupHook() 删除此类挂钩,它们具有相同的签名。 回调以后进先出的顺序运行。

    If necessary, there is an additional pair of AddEnvironmentCleanupHook() and RemoveEnvironmentCleanupHook() overloads, where the cleanup hook takes a callback function. This can be used for shutting down asynchronous resources, such as any libuv handles registered by the addon.

    以下的 addon.cc 使用 AddEnvironmentCleanupHook

    1. // addon.cc
    2. #include <node.h>
    3. #include <assert.h>
    4. #include <stdlib.h>
    5. using node::AddEnvironmentCleanupHook;
    6. using v8::HandleScope;
    7. using v8::Isolate;
    8. using v8::Local;
    9. using v8::Object;
    10. // 注意:在实际的应用程序中,请勿依赖静态/全局的数据。
    11. static char cookie[] = "yum yum";
    12. static int cleanup_cb1_called = 0;
    13. static int cleanup_cb2_called = 0;
    14. static void cleanup_cb1(void* arg) {
    15. Isolate* isolate = static_cast<Isolate*>(arg);
    16. HandleScope scope(isolate);
    17. Local<Object> obj = Object::New(isolate);
    18. assert(!obj.IsEmpty()); // 断言 VM 仍然存在。
    19. assert(obj->IsObject());
    20. cleanup_cb1_called++;
    21. }
    22. static void cleanup_cb2(void* arg) {
    23. assert(arg == static_cast<void*>(cookie));
    24. cleanup_cb2_called++;
    25. }
    26. static void sanity_check(void*) {
    27. assert(cleanup_cb1_called == 1);
    28. assert(cleanup_cb2_called == 1);
    29. }
    30. // 将此插件初始化为上下文感知的。
    31. NODE_MODULE_INIT(/* exports, module, context */) {
    32. Isolate* isolate = context->GetIsolate();
    33. AddEnvironmentCleanupHook(isolate, sanity_check, nullptr);
    34. AddEnvironmentCleanupHook(isolate, cleanup_cb2, cookie);
    35. AddEnvironmentCleanupHook(isolate, cleanup_cb1, isolate);
    36. }

    通过运行以下命令在 JavaScript 中进行测试:

    1. // test.js
    2. require('./build/Release/addon');