如何使用 node.js 中的 C++ 库?

IT技术 javascript c++ node.js binding
2021-02-09 17:17:12

如何使用 node.js 中的 C++ 库?

6个回答

现在这个问题有了新的答案。SWIG,从 3.0 版开始,似乎为 Node.js、Webkit 和 v8提供了javascript 接口生成器

我已经将 SWIG 广泛用于 Java 和 Python 一段时间了,一旦您了解 SWIG 的工作原理,就几乎不需要将 C++ 代码连接到 SWIG 的语言所需的工作(与 ffi 或目标语言中的等效语言相比)支持。

举一个小例子,假设你有一个带有头文件 myclass.h 的库:

#include<iostream>

class MyClass {
        int myNumber;
public:
        MyClass(int number): myNumber(number){}
        void sayHello() {
                std::cout << "Hello, my number is:" 
                << myNumber <<std::endl;
        }
};

为了在 node 中使用这个类,您只需编写以下 SWIG 接口文件 (mylib.i):

%module "mylib"
%{
#include "myclass.h"
%}
%include "myclass.h"

创建绑定文件 binding.gyp:

{
  "targets": [
    {
      "target_name": "mylib",
      "sources": [ "mylib_wrap.cxx" ]
    }
  ]
}

运行以下命令:

swig -c++ -javascript -node mylib.i
node-gyp build

现在,从同一文件夹运行节点,您可以执行以下操作:

> var mylib = require("./build/Release/mylib")
> var c = new mylib.MyClass(5)
> c.sayHello()
Hello, my number is:5

即使我们需要为这样一个小示例编写 2 个接口文件,请注意我们如何MyClass不必在sayHello任何地方提及构造函数和方法,SWIG 发现这些东西,并自动生成自然的接口。

因此,您可以通过两种方式查看 SWIG:它是一种工具,可以开箱即用,并遵守其规则。这意味着,您不应该期望看到 javascript 数组从返回数组的 C++ 函数中弹出。相反,您可以做的是将您的函数包装在 C++ 中,以便它返回一个行为类似于数组的对象(std::vector<>例如, just %include "std_vector.i"),并且您将能够以一种有点尴尬的方式在 javascript 端操作它。请注意,这种方法仍然比自己编写 FFI 更容易、更安全。
2021-03-17 17:17:12
@George SWIG 确实是一个了不起的工具,但它并不神奇,也不是一些可以理解 C++ 代码语义并生成相应界面的通用 AI。请注意 C++ 和 javascript 的语义、所有权概念和生命周期管理有何根本不同。
2021-03-20 17:17:12
使用 SWIG 的另一种方法是了解下面的机制。花几个月的时间使用它,深入了解它的功能。然后你可以让它生成你想要的界面。您希望它为 C++ 数组返回一个 javascript 数组,很好,您可以这样做,但是您首先应该学习如何在这样的接口中表达您期望的确切语义,并确保它很好地映射到您的问题域。
2021-03-23 17:17:12
无论哪种方式,我都建议您从第一种方法开始,并在此过程中完善您对 SWIG 的使用。研究 SWIG 对您的代码做了什么以及如何操作它是非常鼓舞人心的。
2021-04-01 17:17:12
在玩了一会儿 swig/node.js 之后,swig 似乎无法处理返回数组的 C++ 函数(更准确地说:返回指向数组的指针的函数)。也就是说,您似乎无法在 C++ 中构建一个函数来返回类似 JavaScript 数组的内容并让 swig 自动为您转换它。
2021-04-11 17:17:12

看看node-ffi

node-ffi 是一个 Node.js 插件,用于使用纯 JavaScript 加载和调用动态库。它可用于创建与本机库的绑定,而无需编写任何 C++ 代码。

我知道这个评论已经一年多了,但是......是否可以在没有 C 包装器的情况下使用 C++ 库?
2021-03-22 17:17:12
我遇到了 node-ffi 的 VS 2017/2019 编译问题。这是一个重要的皮塔饼!它依赖于 Python 2.7 还是只是构建过程?对于标准的 Win32 DLL,NodeJS 中必须有 LoadLibrary 机制吗?
2021-03-31 17:17:12
不同的 C++ 编译器创建不同的 ABI,因此要使用 node-ffi,您可能必须用 C 接口包装 C++ 代码 - 或者至少我这样做是为了使用 Visual Studio 在 Windows 上运行它。有关如何执行此操作的详细信息,请参阅stackoverflow.com/questions/2045774/...。或者我应该能够在没有包装器的情况下在 C++ 上使用 node-ffi 吗?
2021-04-03 17:17:12
不再支持 node-ffi 并且不能无缝编译,不推荐。
2021-04-06 17:17:12

您可以使用 node.js 扩展为 C++ 代码提供绑定。这是一个涵盖该内容的教程:

http://syskall.com/how-to-write-your-own-native-nodejs-extension

您可以使用emscripten将 C++ 代码编译成 js。

-如果 OP 的目标是获得编译 C++ 的性能优势- 一些好处可以通过 emscripten 进行转换,尤其是 WASM:没有 GC 开销、更少的解析和 JIT 开销、原生整数、AOT 优化。
2021-03-16 17:17:12
如果 OP 的目标是获得编译 C++ 的性能优势,那么这将是一个坏主意,而且迂腐它没有回答问题。
2021-04-04 17:17:12
@Greg 但仍然是一个值得考虑的想法。人们来到这个页面是为了手头的各种类型的项目。当您拥有 C/C++ 代码库并且只想在 Nodejs 中使用它时,我认为 Emscripten 是一个不错的选择。
2021-04-06 17:17:12

有更新的方法来连接 Node.js 和 C++。拜托,掠夺

编辑 最快和最简单的方法是nbind如果你想编写异步附加组件,你可以结合Asyncworker来自 nan 的类。