LoginSignup
2
2

More than 5 years have passed since last update.

Node.jsからC++のクラス・関数をSWIGを使って楽して扱う

Last updated at Posted at 2018-08-17

Node.jsからC++の関数やクラスを扱いたいことがある。例えば、C++で書いたコードのGUIをElectronやNw.jsで書きたいときなど。

一般に、NodeからC++のコードを呼ぶ際は、Node-ffiが使われているようだ。しかしながら、チュートリアルを読んでみると、何やら書く気が雲散霧消してしまう面倒さである。

PythonやRubyからC/C++の関数を呼ぶバインディングの作成ツールとしては、SWIGが知られている。実はこのSWIGを使えば、Javascriptのラッパも手軽に書くことができる。

インストール

SWIGの安定版は3.0.12だが、これはNode 7以降に対応していない。Githubの開発版を使おう。なお、ライブラリのビルドにはNode-gypが必要なので、なければnpmからインストールする。

wget https://github.com/swig/swig/archive/master.zip
unzip master.zip
cd swig-master
./autogen.sh
./configure
make
sudo make install

ラッパを書く

練習に、次のコードをNodeから読んでみよう。

complex.hpp:

#include <string>

struct complex
{
    complex(double r=0,double i=0);
    double re;
    double im;
    double abs()const;
    std::string to_str()const;
};

complex.cpp:

#include <cmath>
#include "complex.hpp"

complex::complex(double r,double i): re(r), im(i) {}
double complex::abs()const{ return std::sqrt(re*re+im*im); }
std::string complex::to_str()const{ return std::to_string(re)+"+"+std::to_string(im)+"i"; }

例えば、このコードが以下のJSから呼べたら素敵ではないだろうか。

complex.js:

const Complex=require('./complex.node').complex;

let z=new Complex();
console.log(z.abs()); // 0と表示してほしい
z.re=3;
z.im=4;
console.log(z.abs()); // 5と表示してほしい
console.log(z.to_str()); //3+4iのような表示を期待

SWIGを使えば、これだけのラッパを書くだけで良い。

complex.i:

%module complex // 外から見えるモジュールを定義
%{
#include "complex.hpp" // この中の関数が外から見える
%}

%include "std_string.i" // これを書いとけばいい感じにstd::stringをJSの文字列にラップしてくれる
%include "complex.hpp"

あとは、ビルド用にbinding.gypを書き、SWIGを実行してビルドするだけ。

binding.gyp:

{ "targets": [ { 
    "target_name": "complex",
    "sources": [ "complex.cpp", "complex_wrap.cxx" ]
} ] }

実行する。

swig -javascript -node -c++ complex.i
node-gyp configure build

できたcomplex.nodeを適当な場所に移して、node complex.jsを実行すると……

0
5
3.000000+4.000000i

簡単!

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2