swig - C++ 到 JavaScript

Mum*_*wiz 5 javascript c++ swig v8 node.js

我正在尝试使用我的 cpp 文件中的 swig 构建一个简单的 javascript 模块。我运行了所有正确的命令,但似乎没有任何效果。\n这是我的.h文件

\n\n
#pragma once\n\nclass Die\n{\npublic:\n    Die();\n    Die(int a);\n    ~Die();\n    int foo(int a) ;\n    Die* getDie(int a);\n    int myVar;\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的.cpp文件:

\n\n
 #include <iostream>\n#include "example.h"\nint Die::foo(int a) {\n\n    std::cout << "foo: running fact from simple_ex" <<std::endl;\n    return 1;\n}\n\nDie::Die(){}\nDie::Die(int a){myVar = a;}\nDie::~Die(){}\nDie* Die::getDie(int a) {\n    return new Die (a);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的.i文件:

\n\n
%module example\n%{\n#include "example.h"\n%}\n%include "example.h"\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的binding.gyp文件:

\n\n
{\n  "targets": [\n    {\n      "target_name": "example",\n      "sources": ["example.cpp", "example_wrap.cxx" ]\n    }\n  ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我遵循了文档中的所有命令swig

\n\n

我跑:

\n\n
sudo apt-get install libv8-dev\nsudo apt-get install libjavascriptcoregtk-1.0-dev\nswig -c++ -javascript -node example.i\nnode-gyp configure build\n
Run Code Online (Sandbox Code Playgroud)\n\n

运行最后一个命令后,我收到各种错误:

\n\n
error: \xe2\x80\x98NewSymbol\xe2\x80\x99 is not a member of \xe2\x80\x98v8::String\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n\n

还有很多很多......\n任何帮助都可以。

\n\n

谢谢!

\n

小智 1

我尝试了这个例子来自己学习这个界面。
为了帮助其他可能偶然发现这一点的人,这里有一个如何使用 swig 和 js 的示例。

首先,我们使用 swig 正在学习的基于对象的方法编写 C++ 类及其逻辑。

#pragma once

class Die
{
public:
    Die(int a);
    ~Die();
    int foo(int a);
    int myVar;
};

extern "C" 
{
    Die* getDie(int a);
}
Run Code Online (Sandbox Code Playgroud)

这里有趣的是,我们并不总是创建一个新实例,而是使用外部函数向我们提供一个指向该类的指针,然后可以使用该指针将其导入到我们的 Javascript 中。这就是 swig 的真正含义。

这是实现:

#include <iostream>
#include "example.h"
int Die::foo(int a) 
{
    std::cout << "foo: running fact from simple_ex" << std::endl;
    return 1;
}

Die::Die(int a)
{
    myVar = a;
}

Die::~Die()
{

}

extern "C" 
{

    Die* getDie(int a) 
    {
        return new Die(a);
    }

}
Run Code Online (Sandbox Code Playgroud)

这里还有一个函数,用于获取所述指针被封装在 extern C 中,这就是我们将其与其他类实现分开的方式,同时也为编译器提供了一些帮助。

swig 界面与问题中的界面相同。它用于生成 swig 的包装文件,为我们提供 Javascript 和 C++ 库之间的实现接口

%module example
%{
#include "example.h"
%}
%include "example.h"
Run Code Online (Sandbox Code Playgroud)

这会在终端中使用以下语句创建包装文件:

swig -c++ -javascript -node example.i
Run Code Online (Sandbox Code Playgroud)

现在我们需要一些 Javascript 工具来构建它:

你需要安装 NodeJs 和 NPM 才能使用以下东西。

首先我们需要一个 package.json 文件:

{
    "name": "SwigJS",
    "version": "0.0.1",
    "scripts": {
      "start": "node index.js",
      "install": "node-gyp clean configure build"
      
    },
    "dependencies": {
      "nan": "^2.16.0",
      "node-gyp": "^9.0.0"
    }
}
Run Code Online (Sandbox Code Playgroud)

这对于让构建程序了解有关包及其依赖项的一些信息非常重要。

之后我们创建一个名为“binding.gyp”的文件

{
  "targets": [
    {
      "target_name": "SwigJS",
      "sources": [ "example_wrap.cxx", "example.cpp" ],
      "include_dirs" : [ "<!(node -e \"require('nan')\")" ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

这保存了我们的构建目标以及 nan 的信息。

为了使其正常工作,我们现在需要创建 .node 文件。这是通过使用以下任一方法来完成的:

node-gyp configure
node-gyp build
Run Code Online (Sandbox Code Playgroud)

或使用:

npm i
Run Code Online (Sandbox Code Playgroud)

两者的作用与我看来几乎相同。(如果我错了请纠正我)

最后,我们现在实现了 Javascript 并使用那里的库。还有一些更多的技巧可以使顶部的路径消失,这样你就可以只写 require("modulname") 但对于这个例子来说这实际上已经太多了。

const Swigjs = require("./build/Release/SwigJS.node");

console.log("exports :", Swigjs); //show exports to see if we have a working library

die = Swigjs.getDie(5); //get the Class pointer

console.log("foo:" + die.foo(5)); //call a function from the class
Run Code Online (Sandbox Code Playgroud)

我希望这有助于清楚地了解 swig 和 js 如何协同工作