I am trying the c++ plugin in nodejs, this is my test code
let obj = new addon.MyClass(function (v) {
console.log(v);
});
obj.run(1);
setTimeout(() => {
obj.run(3); // [TypeError: obj.run is not a function]
}, 1000);
When I call the function again with a delay of one second in js, this error will appear
obj.run(3);
^
[TypeError: obj.run is not a function]
This is the C++ code of the plug-in. The plug-in exports an object. When instantiating the object in js, a callback function needs to be initialized. When the run function is called, the callback is called. I don't know where the problem is. How can I fix the code
#include <node.h>
#include <node_object_wrap.h>
using namespace v8;
#define V8_STR(str) String::NewFromUtf8(isolate, str, NewStringType::kNormal).ToLocalChecked()
class MyClass : public node::ObjectWrap
{
private:
Eternal<Context>* context_;
Eternal<Function>* cb_;
public:
explicit MyClass(Eternal<Context>* context, Eternal<Function>* cb) : cb_(cb), context_(context) {
}
static void Init(Local<Object> exports) {
Isolate* isolate = exports->GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Local<ObjectTemplate> class_tpl = ObjectTemplate::New(isolate);
class_tpl->SetInternalFieldCount(1);
Local<Object> obj = class_tpl->NewInstance(context).ToLocalChecked();
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New, obj);
tpl->SetClassName(V8_STR("MyClass"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(tpl, "run", run);
Local<Function> constructor = tpl->GetFunction(context).ToLocalChecked();
obj->SetInternalField(0, constructor);
exports->Set(context, V8_STR("MyClass"), constructor).FromJust();
};
static void New(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Eternal<Context> e_context(isolate, isolate->GetCurrentContext());
Eternal<Function> e_cb(isolate, args[0].As<Function>());
MyClass* obj = new MyClass(&e_context, &e_cb);
obj->Wrap(args.This());
}
static void run(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope scope(isolate);
auto context = Context::New(isolate);
MyClass* self = ObjectWrap::Unwrap<MyClass>(args.Holder());
const unsigned argc = 1;
Local<Value> argv[argc] = { args[0] };
// call callback
self->cb_->Get(isolate)->Call(context, Null(isolate), argc, argv);
}
};
void Initialize(Local<Object> exports) {
MyClass::Init(exports);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
my node version
λ node -v
v14.15.4