2

我正在尝试使用 JS 回调来初始化我的节点插件模块以进行日志记录。Initialize 方法旨在存储回调值,以便从其他方法调用。所以我使用 . 添加对回调的引用napi_create_reference

但是当我试图从我的第二个插件方法调用回调时,MyAddonMethod我收到napi_invalid_arg错误。

我试图调查这个问题。napi_typeof对回调值的调用也MyAddonMethod返回napi_invalid_arg。尽管我有强烈的参考,但看起来回调值被垃圾收集了。

我究竟做错了什么?实际上是否napi_create_reference可以防止回调对象在插件调用之间被垃圾收集?

// JS side:
const addon = require('./addon.node');
function logCallbackFunction(logLine)
{
    console.log("Trace: " + logLine);
}
addon.Initialize(logCallbackFunction);
addon.MyAddonMethod();

// C++ side
// Initialize method:
napi_ref ref;
napi_create_reference(env, value, 1, &ref);
g_Value = value; // store the value somewhere between calls

// MyAddonMethod method: // "env" doesn't change from call to call
napi_valuetype type;
napi_status stat = napi_typeof(env, g_Value, &type); // napi_invalid_arg
4

1 回答 1

2

我终于发现我做错了什么。它没有资格g_Value在调用之间存储。相反napi_ref,应该存储和napi_get_reference_value使用函数以提取相应的值。所以 C++ 端代码应该是这样的:

// Initialize method:
napi_ref ref;
napi_create_reference(env, value, 1, &ref);
g_Ref = ref; // store the reference somewhere between calls

// MyAddonMethod method:
napi_value referenceValue;
napi_get_reference_value(env, g_Ref, &referenceValue);
napi_valuetype type;
napi_status stat = napi_typeof(env, referenceValue, &type); // napi_ok, napi_function

当然,您不应该忘记在napi_delete_reference不再需要引用时释放引用。

于 2019-07-11T11:29:50.997 回答