首先,我得到了两个nodejs本机插件。第一个包含使用V8对象内部字段暴露的静态C 对象" conn",如嵌入式指南中所述
NAN_METHOD(cobject) {
auto isolate = Isolate::GetCurrent();
Conn* p = &ConnHolder::connection;
Local<ObjectTemplate> conn_templ = ObjectTemplate::New(isolate);
conn_templ->SetInternalFieldCount(1);
Local<Object> obj = conn_templ->NewInstance();
obj->SetInternalField(0, External::New(isolate, p));
info.GetReturnValue().Set(obj);
}
在我的另一个本地插件中,我正在使用C 代码加载第一个,并且我揭示了一个称为test的函数,该函数包含两个呼叫" CallTodummyFunction()"one_answers" CallTofunction WorkwithMemberAccess()"
// persistent handle for the main addon
static Persistent<Object> node_main;
void Init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
// get `require` function
Local<Function> require = module->Get(String::NewFromUtf8(isolate, "require")).As<Function>();
Local<Value> args[] = { String::NewFromUtf8(isolate, "path_to_my_addon\addon.node") };
Local<Object> main = require->Call(module, 1, args).As<Object>();
node_main.Reset(isolate, main);
NAN_EXPORT(exports, test);
}
NAN_METHOD(test) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
// get local handle from persistent
Local<Object> main = Local<Object>::New(isolate, node_main);
// get `cobject` function to get pointer from internal field
Local<Function> createdMain = main->Get(String::NewFromUtf8(isolate, "cobject")).As<Function>();
Local<Object> callResult = createdMain->Call(main, 0, nullptr).As<Object>();
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
// from there i get a pointer to my Conn object
Conn* con = static_cast<Conn*>(ptr);
conn->callToDummyFunction();
conn->callToFunctionWithMemberAccess();
info.GetReturnValue().Set(10);
}
然后,我正在使用"节点"启动nodejs会话,我使用两个需要呼叫加载第一个和第二个插件,最后我在第二个插件上调用方法测试。
执行方法测试,成功执行了" callTodummyFunction"的调用,但呼叫" callTofunction withMemberAccess"崩溃并杀死节点会话。
好,那么" calltodummyfunction"one_answers" callTofunction withMemberAccess"?
之间有什么区别?bool Conn::callToDummyFunction()
{
cout << "callToDummyFunction" << endl;
return true;
}
bool Conn::callToFunctionWithMemberAccess()
{
cout << "callToFunctionWithMemberAccess " << someIntMember << endl;
return true;
}
因此,似乎访问conn对象的成员会生成错误并崩溃节点会话。节点会话在崩溃之前不会输出任何消息。
有人可以告诉我为什么吗?
和/或
如何获取错误消息?
我正在回答自己的问题。实际上,我很愚蠢,但至少我的愚蠢使我学习了一些奇怪的CPP。
所以,首先是愚蠢的答案。而不是使用返回的对象,而是使用一个完全无关的对象:(
Local<Object> callResult = createdMain->Call(main, 0, nullptr).As<Object>();
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
为什么使用
local self = info.holder();
而不是呼叫。正确的代码将是
Local<Object> callResult = createdMain->Call(main, 0, nullptr).As<Object>();
Local<External> wrap = Local<External>::Cast(callResult->GetInternalField(0));
我从这个愚蠢的错误中学到了什么:
- 仔细阅读您的代码(明显)
- 如果该功能中没有任何成员访问,则在NULLPTR实际作品上执行成员函数(对于经验丰富的CPP DEV来说是显而易见的)
- 本机插件活在自己的VM中,VM之间没有共享静态字段。