从C ++ Addon

时间:2016-07-19 10:23:00

标签: node.js

我需要一些帮助来解决我的问题。 基本上,我想"打电话"来自C ++插件的javascript函数,我已经搜索过它并发现了类似的内容。

这是我的.js文件

const myaddon = process.binding('myaddon');

function Foo() {
    console.log("wooo");
}
myaddon.getfoo(Foo);
myaddon.callfoo(); // just to test if C++ Call js function work

这是我的.cpp

Local<Function> pfOnScriptInit;
Local<Object> globel;
void test(const FunctionCallbackInfo<Value>& args)
{
    pfOnScriptInit = Local<Function>::Cast(args[0]);
}
void call(const FunctionCallbackInfo<Value>& args)
{
    pfOnScriptInit->Call(globel, 0, nullptr);
}
void initAll(Local<Object> target, Local<Value> unused, Local<Context> context, void* priv) 
{
    node::Environment* env = node::Environment::GetCurrent(context);

    globel = env->context()->Global();
    env->SetMethod(target, "getfoo", test); 
    env->SetMethod(target, "callfoo", call);
}
NODE_MODULE_CONTEXT_AWARE_BUILTIN(fivemp, node::fivemp::initAll)

调用myaddon.callfoo();函数时出现此错误:

  

TypeError:非法调用

1 个答案:

答案 0 :(得分:3)

这个问题有点陈旧,但这是一个常见的问题,已被问到couple times。在我看来,这些答案没有正确的答案。因此,我走了!

在我回答您的问题之前,请允许我说您应该使用Native Abstractions for Node.js来编写Node.js插件。这将使您的插件可以跨Node.js版本移植。

此外,您应该查看官方插件文档here,以及带有Nan示例的repo

那就是说,你的代码有一个很大的常见错误:你混淆地使用本地对象作为持久性。换句话说,从函数范围声明ext_tables.sql是完全错误的。这两个不能在功能范围内声明:

Local<Function>

当然,你不能像这样分配Local<Function> pfOnScriptInit; Local<Object> globel;

Local<Function>

这个本地对象将由v8的垃圾收集器回收 - 它将不再存在。因此,您需要使用pfOnScriptInit = Local<Function>::Cast(args[0]); 类型。这是一个使用Nan编写的示例,它可能会告诉您它是如何完成的:

persistent

这是JS方面:

#include <nan.h>

static Nan::CopyablePersistentTraits<v8::Function>::CopyablePersistent _cb;

static void SetCallback(const Nan::FunctionCallbackInfo<v8::Value>& info) {
  _cb = Nan::Persistent<v8::Function>(info[0].As<v8::Function>());
}

static void RunCallback(const Nan::FunctionCallbackInfo<v8::Value>& info) {
  Nan::MakeCallback(Nan::GetCurrentContext()->Global(), Nan::New(_cb), 0, 0);
  _cb.Reset();
}

void RunThisCallback(const Nan::FunctionCallbackInfo<v8::Value>& info) {
  v8::Local<v8::Function> cb = info[0].As<v8::Function>();
  Nan::MakeCallback(Nan::GetCurrentContext()->Global(), cb, 0, 0);
}

static void Init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module) {
  Nan::SetMethod(exports, "setCallback", SetCallback);
  Nan::SetMethod(exports, "call", RunCallback);
  Nan::SetMethod(exports, "callThis", RunThisCallback);
}

NODE_MODULE(addon, Init)

有关v8本地vs持久性的更多信息,您应该查看v8的文档。 Scott Frees还有一本关于Node.js插件的好书,https://scottfrees.com/ebooks/nodecpp/