c++ - Node.js 在 C/C++ 中添加模块

标签 c++ node.js node.js-addon

我一直在探索用 C/C++ 为 node.js 编写附加模块。到目前为止,我有一个简单的附加功能,我可以在其中调用附加功能表单 JavaScript,这非常简单。该例程称为 hello,它传递一个字符串,然后返回以 Hello 为前缀的相同字符串,两个词之间有一个空格。

package.json:

{
    "name":         "test",
    "version":      "2.0.0",
    "description":  "test description",
    "main":         "index.js",
    "gypfile":      true,
    "scripts": {
        "build":    "node-gyp rebuild",
        "clean":    "node-gyp clean"
    },
    "author": "Simon Platten",
    "license": "ISC",
    "devDependencies": {
        "node-gyp": "^7.1.2"
      },
    "dependencies": {
        "node-addon-api": "^3.1.0"
    }
}

绑定(bind).gyp:

{
    "targets":[{
        "target_name":  "test",
        "cflags!":      ["-fno-exceptions"],
        "cflags_cc!":   ["-fno-exceptions"],
        "sources":      ["cpp/main.cpp"],
        "include_dirs": ["<!@(node -p \"require('node-addon-api').include\")"],
        "libraries":    [],
        "dependencies": ["<!(node -p \"require('node-addon-api').gyp\")"],
        "defines":      ["NAPI_DISABLE_CPP_EXCEPTIONS"],
    }]
}

main.cpp

/**
 * File:    main.cpp
 * Notes:
 *  Work in progress for add on module for node.js 'test'
 * History:
 *  2021/03/11 Written by Simon Platten
 */
 #include <napi.h>
 #include <iostream>
 #include <string>
/**
 * Return "Hello " + user name passed back
 */
 Napi::String hello(const Napi::CallbackInfo& info) {
     Napi::Env env = info.Env();
     std::string strResult = "Hello ";
     strResult += info[0].ToString();
     return Napi::String::New(env, strResult);
 }
/**
 * Callback method when module is registered with Node.js
 */
 Napi::Object Init(Napi::Env env, Napi::Object exports) {
     exports.Set(
        Napi::String::New(env, "hello"),
        Napi::Function::New(env, hello)
     );
     return exports;
 }
 NODE_API_MODULE(test, Init);

index.js:

const test = require("./build/Release/test");

console.log(test.hello("Simon"));

效果很好,现在我想尝试一下。我不确定这个的正确术语,但是例如,当在 Node 中使用套接字时,有各种 on 回调或可以使用回调函数管理的事件。这正是我想从我的模块中实现的,该模块将传递大量数据进行处理,我将在模块处理数据时立即返回,当它完成并准备好供我要发布的客户端使用时以 on 样式处理程序的形式向 node.js 发出通知。

如何?

最佳答案

在 JS 中:

创建一个继承自 EventEmitter 的类.这样做您将能够收听此类中的事件。

如果您使用此类的回调调用您的插件函数,并在回调中发出您的事件,您可以实现您想要的。

像这样:

const test = require("./build/Release/test");
const EventEmitter = require('events');

class Test extends EventEmitter {
    constructor() {
        super();
        this.addon = test;
    }

    test() {
        test.hello("Simon", (data) => {
            this.emit("testEvent", data);
        });
    }
}

const myTest = new Test();

myTest.on("testEvent", (data) => {
    console.log("testEvent says: ", data);
})

myTest.test();

在 C++ 中:

基于找到的示例 here ,您可以添加一个 AsyncWorker,它将在后台处理您的数据并在完成后调用回调。

像这样:

#include <napi.h>
#include <iostream>
#include <string>
#include <chrono>
#include <thread>

using namespace Napi;

class TestWorker : public AsyncWorker {
public:
    TestWorker(Function& callback) : AsyncWorker(callback) {}

    void Execute() override {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    void OnOK() override {
        HandleScope scope(Env());
        Callback().Call({String::New(Env(), "message from the addon")});
    }
};

您可以将此回调作为参数提供给您的 hello 函数以及您当前的参数“Simon”。

您的代码扩展了回调参数和 AsyncWorker 的启动:

 Napi::String hello(const Napi::CallbackInfo& info) {
     Napi::Env env = info.Env();
     std::string strResult = "Hello ";
     strResult += info[0].ToString();
     Function cb = info[1].As<Function>();
     TestWorker* wk = new TestWorker(cb);
     wk->Queue();
     return Napi::String::New(env, strResult);
 }

关于c++ - Node.js 在 C/C++ 中添加模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66584229/

相关文章:

c++ - 使用Clang LibTooling扫描已调用模板化父类中的本地类的C++源

c++ - 将 char* 复制到指定位置的 std::string 不分配新对象

c++ - 在 C++ 中查找和存储超像素邻域的算法和数据结构

node.js - Nodejs 与 koa 和 Mongo - MongooseError : You can not `mongoose.connect()` multiple times while connected

javascript - Sequelize : find latest record per group of id

c++ - 在具有结构的 vector 中获取项目位置

node.js - Postman 可以工作,但 Fetch 不能。我究竟做错了什么?

c++ - 可读 Node 流到 native c++ 插件 InputStream

c++ - 未分配正在释放的 native node.js 插件错误指针

c++ - 将节点数组(可变长度)转换为 const float** 以调用 opencv.calcHist