在void *中为Node.js插件检索和存储V8对象

我试图存储从JavaScript传递到Node.js插件在void * 。 我似乎无法得到这个编译; 用node-gyp构build会产生error: no matching function for call to 'Cast'

我试图做的长版本是编写一个运行Csound的Node.js插件。 Csound从鸟瞰的angular度出发,用C函数作为(通常)第一个参数,将一个指向不透明的Csound结构的指针。 这个结构包含一个void *到“ hostData ”,由一个托pipeCsound的程序设置的任意数据。 Csound所做的一些事情,比如发布消息,在这种情况下用callback函数指针进行修改。 我需要一个地方为Csound的每个实例存储callback,所以我想让某人从JavaScript设置hostData到一个对象,但是我也想把Csound实例的callback设置为这个hostData对象的隐藏属性 。

我认为代码将需要看起来像

 #include "csound.h" #include <node.h> static void CsoundMessageCallback(CSOUND *Csound, int attributes, const char *format, va_list valist) { // Call the JavaScript function we stored in the hostData of Csound. } static void _wrap_csoundSetMessageCallback( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(v8::Isolate::GetCurrent()); CSOUND *Csound; // Pretend we get the Csound instance from args[0] here. This is actually done // by SWIG <http://www.swig.org>. // This does not compile. csoundGetHostData() returns a void *, but I'm assuming // hostData was set to an object from JavaScript. v8::Persistent<v8::Object> hostData = v8::Persistent<v8::Object>::Cast(csoundGetHostData(Csound)); hostData.SetHiddenValue( v8::String::New("CsoundMessageCallback"), v8::Persistent<v8::Function>::Cast(args[1]) ); csoundSetMessageCallback(Csound, CsoundMessageCallback); } 

我猜我需要仔细看看V8的内部领域,但是我真的不确定。

通常我在这种情况下所做的是我编写一个包装器C ++类(inheritance自节点的ObjectWrap类),它存储一个指向我包装的任何C / C ++类的实例的指针,并且具有各种公共方法实例。

当从JS领域调用new ,一个新的包装器C ++类的实例被创build并且与新的JS对象相关联。 然后你有JS函数,启动利用包装库的callback的任何asynchronous任务。

从那里它只是从包装库的callback中调用uv_async_send()来发信号通知主线程,然后从uv_asynccallback中调用JScallback。

你可以在这里看到所有的例子(特别是在Windows特定的部分):

  • Pcap类包含一个pcap_t指针(对于你来说是一个CSOUND指针)。
  • 当从JS land创build新的Pcap ,我会包装一个新的C ++类实例 。
  • 初始化一个uv_async_t ,它设置要在uv_async_send()uv_async_send() 的callback uv_async_send() , 并将用户数据指针关联到类实例以便于访问。 你可以在调用new过程中做这个初始化,如果你想,而不是像初学者那样做一个单独的原型函数( open() )。
  • 然后从包装库的callback ,我发信号的主线程。
  • 从uv_asynccallback中,我可以访问包装类实例并安全地使用V8函数。 虽然在我的情况下,我有另一个使用V8函数的callback 。 但是你可以在你的uv_asynccallback中安全地使用它们。

至于存储JScallback,有不同的方法来处理。 一种解决scheme可能是创build一个baton对象,该对象存储JScallback的持久副本和包装器类实例,并将该接力器存储在uv_async_t的用户数据指针中。 这意味着要为每个请求创build一个新的uv_async_t (这与上面给出的示例不同)。