我试图将从 JavaScript 传递到 Node.js 插件的对象存储在 void *
中。我似乎无法编译它;使用node-gyp构建会产生错误:没有调用“Cast”的匹配函数
。
我想做的长版本是编写一个运行 Csound 的 Node.js 插件。从鸟瞰角度来看,Csound 与 C 函数一起工作,这些函数将指向不透明 Csound 结构的指针作为(通常)第一个参数。该结构包含一个 void *
到“hostData
”,由托管 Csound 的程序设置的任意数据。 Csound 所做的一些事情(例如发布消息)是通过回调(在本例中为函数指针)进行修改的。我需要一个地方来存储每个 Csound 实例的回调,因此我尝试让某人将 hostData
设置为 JavaScript 中的对象,但我也想将 Csound 实例的回调设置为 hidden properties在此 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++ 类(继承自 Node 的 ObjectWrap 类),该类存储指向我正在包装的任何 C/C++ 类的实例的指针,并且具有各种公共(public)方法与该实例交互。
何时 new
从 JS 领域调用,将创建包装器 C++ 类的新实例并与新的 JS 对象关联。然后,您可以使用 JS 函数来启动利用包装库的回调的任何异步任务。
从那里只需调用 uv_async_send()
即可从包装库的回调向主线程发出信号,然后从 uv_async 回调调用 JS 回调。
您可以看到所有这些的示例 here (特别是在 Windows 特定部分):
Pcap
类(class)持有pcap_t
指针(对你来说就是CSOUND
指针)。- 当一个新的
Pcap
是从JS土地创建的,我wrap a new C++ class instance . - Initialize a
uv_async_t
设置 the callback开火uv_async_send()
还有associates the user data pointer到类实例以便于访问。您可以在调用new
期间执行此初始化如果您愿意,而不是像我所做的那样使用单独的原型(prototype)函数(open()
),因为初始化只发生一次。 - 然后来自 the wrapped library's callback ,我signal主线程。
- 通过 uv_async 回调,我可以 access the wrapper class instance并安全地使用 V8 功能。尽管在我的具体情况下,我有 another callback它使用 V8 函数。不过,您可以在 uv_async 回调中安全地使用它们。
就存储 JS 回调而言,有不同的方法来处理它。一种解决方案可能是创建一个指挥棒对象来存储 JS 回调和包装类实例的持久拷贝,并将该指挥棒存储在 uv_async_t
中。的用户数据指针。这意味着创建一个新的 uv_async_t
对于每个请求(这与我上面给出的示例不同)。
关于c++ - 在 Node.js 插件的 void * 中检索和存储 V8 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32430748/