【问题标题】:C++ V8 object contextC++ V8 对象上下文
【发布时间】:2012-11-21 07:36:34
【问题描述】:

我正在尝试在 C++ 中执行回调(其中 C++ 作为 node.js 程序的一部分运行)。回调是到第 3 方库,当它有数据要传递时,它将调用回调。

我似乎遇到的问题是变量类型:

static void sensorEventCallback(const char *protocol, const char *model,
        int id, int dataType, const char *value, int timestamp,
        int callbackId, void *context)
{
   //process the data here
}

Handle<Value> sensorEvents( const Arguments& args ) {
    HandleScope scope;
    ...
    callbackId = tdRegisterSensorEvent(
            reinterpret_cast<TDSensorEvent>(&telldus_v8::sensorEventCallback),
            Context::GetCurrent()->Global());
}

我得到的错误:

错误:无法将“v8::Local<:object>”转换为“void*”作为参数 ‘2’ to ‘int tdRegisterSensorEvent(void ()(const char, const char*, int, int, const char*, int, int, void*), void*)'

它似乎在与作为上下文的论点 2 作斗争。关于如何将 V8 对象转换为 tdRegisterSensorEvent 可以接受的对象有什么想法吗?

【问题讨论】:

  • 看起来你需要传递对象的地址而不是对象本身。
  • @n.m.不应该提倡cargo cult programming(尤其是当 v8.h 是发布源时)Context::GetCurrent()-&gt;Global() 返回一个 Local&lt;Context&gt;...
  • @HostileFork:我应该说“一个对象”而不是“对象”,对此我深表歉意。如果 C 函数需要 void*,您通常会向它传递一些对象的地址。我没有别的意思。

标签: c++ node.js


【解决方案1】:

窥探一下,GetCurrent 似乎在 V8 标头中定义以返回 Local&lt;Context&gt;

v8.h on GitHub, location of GetCurrent() in the Context object definition

这个Local&lt;T&gt; 是一个“轻量级堆栈分配句柄”的模板,它派生自基类Handle&lt;T&gt;

v8.h on GitHub, definition of Local

v8.h on GitHub, definition of Handle

看来你有一个上下文指针,它的生命周期由一个叫做HandleScope 的东西管理。如果您将上下文指针拉出并保存以供稍后在回调中使用,它可能在调用时仍然存在,也可能不存在。

如果您知道所有回调将在句柄范围释放之前发生,您可以尝试使用解引用运算符重载获取指针并传递它:

v8.h on GitHub, T* Handle::operator*()

但你可能没有这个保证。

【讨论】:

  • 很棒的信息,谢谢!你在理解文档方面做得比我好得多!确实.. 回调可能会在事件注册数小时后发生 - 我必须找到另一种让 node.js 与 c++ 对话并避免使用 Handles 的方法..
  • 文档中似乎没有这些,所以我只是去阅读标题...!
  • @RichW 这就是为什么 Persistant 适合
【解决方案2】:

作为 n.m.说我猜应该传递上下文对象的地址。然后你可以在你的回调中回滚

void telldus_v8::sensorEventCallback(const char *protocol, const char *model,
        int id, int dataType, const char *value, int timestamp,
        int callbackId, void *context)
{
   v8::Local<v8::Object>* ctx_ptr = static_cast<v8::Local<v8::Object>*>(context);
   //process the data here
}

v8::Local<v8::Object> ctx = Context::GetCurrent()->Global();
callbackId = tdRegisterSensorEvent(
        reinterpret_cast<TDSensorEvent>(&telldus_v8::sensorEventCallback),
        &ctx);

【讨论】:

  • 我认为开源革命的好处在于我们不必猜测! :-/ (这是Local&lt;Context&gt;,见my answer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-23
  • 2014-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多