Swig を利用して、Ruby プログラムから C++ のテンプレートクラスを呼び出す

<要点>

関連する外部ページhttp://www.swig.org/Doc1.3/SWIGPlus.html

Swig を利用して、Ruby プログラムから C++ のテンプレートクラスを呼び出す例

  1. C++ プログラムの作成

    例えば、次のように triple.hpp を作成. C++ のテンプレートクラスでは,ヘッダファイルに,クラス定義を全て書くことに注意

    template<class T> class Triple {
    private:
      T _x;
      T _y;
      T _z;
    public:
      Triple() {};
      ~Triple() {};
      void set_x( const T& arg ) { this->_x = arg;  return; }; 
      void set_y( const T& arg ) { this->_y = arg;  return; };  
      void set_z( const T& arg ) { this->_z = arg;  return; };  
      T x() { return this->_x; }; 
      T y() { return this->_y; }; 
      T z() { return this->_z; }; 
    };
    
  2. triple.i の作成

    モジュール名を MyCPP に設定している.

    %module MyCPP
    %{
    #include "triple.hpp"
    %}
    %include "triple.hpp"
    %template(IntTriple) Triple<int>; 
    
  3. swig の実行
    rm -f triple_wrap.*
    swig2.0 -ruby -c++ triple.i 
    
  4. extconf.rb の作成

    「create_makefile('MyCPP')」と記述しているので、MyCPP.so が生成されることになる

    require 'mkmf'
    
    dir_config('triple')
    $libs += " -lstdc++ "
    if have_header('triple.hpp') 
      create_makefile('MyCPP')
    end
    
  5. ビルド
    ruby extconf.rb
    make CC=g++
    

    nm で確認してみる

  6. インストール
    sudo make site-install
    
  7. 使ってみる
    irb
    
    require 'MyCPP'
    a = MyCPP::IntTriple.new
    a.set_x(1)
    a.set_y(2)
    a.set_z(3)
    a.x
    a.y
    a.z 
    

C++ のヘッダファイルで namespace を使っている場合

Swig では C++ のヘッダファイル内の namespace は無視される(その結果、競合が起きる場合のために競合を避けるための機能もあります)。

  1. C++ プログラムの作成

    例えば、次のように triple.hpp を作成. C++ のテンプレートクラスでは,ヘッダファイルに,クラス定義を全て書くことに注意

    
    namespace hoge {
      template<class T> class Triple {
      private:
        T _x;
        T _y;
        T _z;
      public:
        Triple() {};
        ~Triple() {};
        void set_x( const T& arg ) { this->_x = arg;  return; }; 
        void set_y( const T& arg ) { this->_y = arg;  return; };  
        void set_z( const T& arg ) { this->_z = arg;  return; };  
        T x() { return this->_x; }; 
        T y() { return this->_y; }; 
        T z() { return this->_z; }; 
      };
    }
    
  2. triple.i の作成

    モジュール名を MyCPP に設定している.

    %module MyCPP
    %{
    #include "triple.hpp"
    %}
    %include "triple.hpp"
    %template(IntTriple) hoge::Triple<int>; 
    
  3. swig の実行
    rm -f triple_wrap.*
    swig2.0 -ruby -c++ triple.i 
    
  4. extconf.rb の作成

    「create_makefile('MyCPP')」と記述しているので、MyCPP.so が生成されることになる

    require 'mkmf'
    
    dir_config('triple')
    $libs += " -lstdc++ "
    if have_header('triple.hpp') 
      create_makefile('MyCPP')
    end
    
  5. ビルド
    ruby extconf.rb
    make CC=g++
    

    nm で確認してみる

  6. インストール
    sudo make site-install
    
  7. 使ってみる
    irb
    
    require 'MyCPP'
    a = MyCPP::IntTriple.new
    a.set_x(1)
    a.set_y(2)
    a.set_z(3)
    a.x
    a.y
    a.z