【问题标题】:Callback function in Node.js addonNode.js 插件中的回调函数
【发布时间】:2014-08-11 03:01:40
【问题描述】:

我在 node.js 扩展中封装了一个 CAN 总线管理器 API。 一切正常,这将是最终结果:

// list interfaces
var interfaces = addon.listDevices();
console.log(interfaces);

// Allocating a new port
var port = new addon.CANPort();
port.setCallback(function(msg) {
    // I would like to receive all CAN datagrams
    console.log(msg);
});

// Connect to the 1st port
port.connect(0);
// Send a datagram
port.sendStruct(127508, 6, Array(0, 70, 5, 50, 0, 131, 114, 0));

除了 setCallback 函数之外,每个函数都可以。其实,我不知道该怎么办。 我有一个这种类型的 c++ 回调:

void CANPort::SetReceiveCallback(functionCallback func);

它会在收到新数据报时调用该函数。

我在http://nikhilm.github.io/uvbook/threads.html 中找到了一些帮助,但我找不到与上一个示例相同的正确方法。我知道我应该使用 uv,但我不知道如何......

另外,我用的是Node.js的v0.11.14-pre,所以很多文档已经过时了……

谢谢, 尼古拉斯。

【问题讨论】:

  • 您不能内联执行此操作:function(msg) { // I would like to receive all CAN datagrams console.log(msg); } 在外部某处声明函数并调用 port.setCallback(function);
  • 为什么不一样?类型是相同的,对吧?也许命名函数和 lambda 函数之间有区别?
  • '为什么不一样?' 因为那不是有效的 c++ 语法老兄!恕我直言,即使是 lambda 也应该首先声明,但那里没有 lambda 声明/定义语法。
  • 你的functionCallback 是什么?我希望你在 cpp 端写了一些有效的 v8 绑定;
  • 那不是 cpp 而是 javascript 代码 :)

标签: javascript c++ node.js add-on


【解决方案1】:

虽然这有点旧,但我使用了混合 javascript/C++ 机制来集成外部回调。基本上用uv_work_t在你的回调中调用uv_queue_work(),它什么都不做,并使用它的after_work_cb来调用你的javascript函数:

// C++

void nop() {}

void jscallback(uv_work_t* handle, int status)
{
  // extract some_data from handle and call node::MakeCallback() here
  // I make it call emit('event', some_data);
  delete handle;
}

void called_by_third_party_callback(some_type some_data)
{
  uv_work_t uv = new uv_work_t();
  if (!uv) {
    // error
  }
  // ensure some_data is accessible via uv->data
  if (uv_queue_work(uv_default_loop(), uv, nop, jscallback) != 0) {
    delete uv;
  }
}

在我的 javascript 方面,我使用字符串到函数的映射在我的 Engine 对象之上实现了一个简单的事件发射器机制:

// Javascript

exports.Engine.prototype.eventMap = [];
exports.Engine.prototype.on = function (name, func) {
  if (typeof (func) === "function") {
    this.eventMap[name] = func;
}

exports.Engine.prototype.emit = function (name, value) {
  var func = this.eventMap[name];
  if (typeof (func) === "function") {
    func(value);
  }
}

我就是这样使用它的:

// Javascript

var obj = new require('myaddon').Engine();

obj.on('event', function (v) {
  console.log('event: ' + v);
});

抱歉过度使用 cmets。我的代码过于复杂,无法显示为片段。

【讨论】:

    猜你喜欢
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多