2016-07-19 96 views
1

我需要一些幫助來解決我的問題。 基本上,我想從C++插件中「調用」javascript函數,我已經使用了它並發現了類似這樣的內容。從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: Illegal Invocation

回答

2

這個問題是有點老,但這是一個常見的問題,它已被問及coupletimes 。在我看來,這些答案沒有一個正確的答案。因此,我走了!

在我回答你的問題之前,讓我說你應該使用本地抽象Node.js來編寫一個Node.js插件。這將使您的插件可跨Node.js版本移植。

另外,你應該看看官方的插件文檔here,以及與0123例子的repo

這就是說,你的代碼有一個很大而且很常見的錯誤:你把一個本地對象當作持久化來使用。換句話說,聲明一個Local<Function>不在函數範圍內是錯誤的。這兩個不能被任何地方說明,但功能範圍:

Local<Function> pfOnScriptInit; 
Local<Object> globel; 

當然,你無法分配Local<Function>這樣的:

pfOnScriptInit = Local<Function>::Cast(args[0]); 

這個本地對象將通過V8的垃圾收集器回收 - 它不會再存在了。因此,您需要使用persistent類型。下面是一個例子,使用楠寫的,這可能會告訴你它是如何做:

#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) 

而這裏的JS方:

var addon = require('bindings')('addon'); 

function foo() { 
     console.log("woohoo!"); 
} 

addon.setCallback(foo); 
addon.call(); 
addon.callThis(() => console.log("this too!")); 

關於V8的地方VS持久欲瞭解更多信息,你應該採取看看v8的文檔。還有一本關於Scott Frees的Node.js插件的書,這裏有https://scottfrees.com/ebooks/nodecpp/