post Image
GO 1.5 と C++ を SWIG でブリッジさせる方法

わかってしまえば簡単なのだが、引っかかることが多いのでメモ。
(検証環境:OSX El Capitan, GO 1.5.1, SWIG 3.0.7)


1 まず引数をエコーさせる単純な例を考える。

ソースディレクトリに以下の3ファイルを作る。

sc1.h
#pragma once 

inline  int
EchoIntN( int p ) {
    return p;
}

inline  double
EchoDoubleN( double p ) {
    return p;
}
sc1.swigcxx
%module sc1
%{
#include    "sc1.h"
%}

%include    "sc1.h"
nop.go
package sc1

以下を実行すると

go install

*. swigcxx があれば自動的に swig が呼び出され、pkg 化されてインストールされる。(GO 1.5 から)
ファイル nop.go は go ファイルが一つもないと go install が失敗してしまうので、その対策用のダミー。他に go ファイルがあれば必要ない。

呼び出し側は実行ディレクトリに以下のファイルを用意して

main1.go
package main

import  "fmt"
import  "github.com/Satachito/sc1"

func
Dump( p interface{} ) {
    fmt.Printf( "%v:%T\n", p, p )
}

func
main() {
    Dump( sc1.EchoIntN( 8 ) );
    Dump( sc1.EchoDoubleN( 9 ) );
}

実行

$ go run main1.go
8:int
9:float64


補足

もし nop.go ファイルを作るのが嫌だったら、sc1.swigcxx を別の名前(例えばsc1.i)に変えて、明示的に swig を呼び出してから go install すれば良い。

swig -go -c++ -cgo -intgosize 32 sc1.i
go install

sc1.go と sc1_wrap.cxx の2つのファイルが同一ディレクトリに作成される。


2 テンプレート化してみる。

sc2.h
#pragma once 

template    <typename T>    T
Echo( const T& p ) {
    return p;
}
sc2.swigcxx
%module sc2
%{
#include "sc2.h"
%}

%include "sc2.h"

%template(EchoIntT)     Echo<int>;
%template(EchoDoubleT)  Echo<double>;

最後の2行でテンプレートを実体化している。

nop.go
package sc2

として

go install

呼び出し側は

main2.go
package main

import  "fmt"
import  "github.com/Satachito/sc2"

func
Dump( p interface{} ) {
    fmt.Printf( "%v:%T\n", p, p )
}

func
main() {
    Dump( sc2.EchoIntT( 8 ) );
    Dump( sc2.EchoDoubleT( 9 ) );
}

$ go run main2.go
8:int
9:float64


3 string を使ってみる。

関数とテンプレート両方用意した。

sc3.h
#pragma once 

template    <typename T>    T
Echo( const T& p ) {
    return p;
}

#include    <string>

inline  std::string
EchoStringN( std::string p ) {
    return p;
}
sc3.swigcxx
%module sc3
%{
#include "sc3.h"
%}


%include    "std_string.i"

%include    "sc3.h"

%template(EchoStringT)  Echo<std::string>;

std_string.i を include するのがポイント

nop.go
package sc3

として

go install

呼び出し側は

main3.go
package main

import  "fmt"
import  "github.com/Satachito/sc3"

func
Dump( p interface{} ) {
    fmt.Printf( "%v:%T\n", p, p )
}

func
main() {
    Dump( sc3.EchoStringN( "Echo me N." ) );
    Dump( sc3.EchoStringT( "Echo me T." ) );
}

$ go run main3.go
Echo me N.:string
Echo me T.:string


4 vector を使ってみる。

sc4.h
#pragma once 

template    <typename T>    T
Echo( const T& p ) {
    return p;
}

#include    <string>
#include    <vector>

inline  std::vector<std::string>
EchoVSN( std::vector<std::string> p ) {
    return p;
}
sc4.swigcxx
%module sc4
%{
#include "sc4.h"
%}


%include    "std_string.i"
%include    "std_vector.i"

%include    "sc4.h"

namespace std {
    %template(StringVector) vector<string>;
}

%template(EchoVST)  Echo<std::vector<std::string>>;

std_vetor.i を include するのがポイント。

nop.go
package sc4

として

go install

呼び出し側は

main4.go
package main

import  "fmt"
import  "github.com/Satachito/sc4"

func
Dump( p interface{} ) {
    fmt.Printf( "%v:%T\n", p, p )
}

func
main() {
    a := sc4.NewStringVector()
    defer sc4.DeleteStringVector( a )
    a.Add( "Echo me." );
    Dump( sc4.EchoVSN( a ).Get( 0 ) );
    Dump( sc4.EchoVST( a ).Get( 0 ) );
}

$ go run main4.go
Echo me.:string
Echo me.:string

NewStringVector, DeleteStringVector, Add, Get は自動的に生成されている。他にもvectorとして扱うために必要なものが生成される。どんなメソッドが生成されているかを見るには、swig を明示的に呼び出して生成された go ファイルの中を見てみる。


5 struct を使ってみる。

sc5.h
#pragma once 

template    <typename T>    T
Echo( const T& p ) {
    return p;
}

struct
IF {
    int     I;
    float   F;
    double  Total() {
        return I + F;
    }
};

IF
EchoIFN( const IF& p ) {
    return p;
}
sc5.swigcxx
%module sc5
%{
#include "sc5.h"
%}

%include    "sc5.h"

%template(EchoIFT)  Echo<IF>;
nop.go
package sc5

として

go install

呼び出し側は

main5.go
package main

import  "fmt"
import  "github.com/Satachito/sc5"

func
Dump( p interface{} ) {
    fmt.Printf( "%v:%T\n", p, p )
}

func
main() {
    a := sc5.NewIF()
    defer sc5.DeleteIF( a )
    a.SetI( 1 )
    a.SetF( 2 )
    w1 := sc5.EchoIFN( a )
    Dump( w1.GetI() );
    Dump( w1.GetF() );
    Dump( w1.Total() );
    w2 := sc5.EchoIFT( a )
    Dump( w2.GetI() );
    Dump( w2.GetF() );
    Dump( w2.Total() );
}

$ go run main5.go
1:int
2:float32
3:float64
1:int
2:float32
3:float64

メンバーには直接アクセスできないので、setter, getter を使う。
忘れがちだけど、GO らしく C の構造体の方のメンバーの名前も最初大文字で。



『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。