graphics.hatenablog.com

技術系テクニカルアーティストのあれこれ

SWIGでハマったメモ。

グラフィックス屋さん的にPythonはとてもだいじ。
なんか見つけたら追記してく。

  • AttributeError: type object 'object' has no attribute '__getattr__'

よくあるあれ、return object.__getattr__(self, name) で落ちる。
SWIG はいわゆる リフレクション で関数を探してくるんだけど、そのときに関数シンボルが見つからなかったよ、というエラー。だいたいタイプミスなので、Python 側のコードを見なおして関数名がちゃんとあってるか確認する。

  • warning 490: Fragment 'SWIG_AsVal_std_string' not found.

STLとかはインターフェイスファイルで指定しないと使えない。こんなかんじ↓

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

定義済みインターフェイスファイルは SWIG の Lib ディレクトリにある。std::unique_ptr がないのは地味に痛い。。(SWIG 3.0.5 時点)

セグフォ的な、一番こまるやつ。自分の手元では C++ 側での不正なメモリ参照なんかが多いっぽい。
OUT とか INOUT の引数をポインタ使ってやってるときに嵌ったりもする。そういうのは真面目に対処しようとするとわりと面倒だし、関数の返り値とかで代替できないか考える余地はありそう。void f(int*) じゃなくて int f() にできないか、みたいな。

  • C++11 が使えない

わりとよくある。部分的にしか対応してないっぽい。

  • 生ポインタでバイナリの受け渡し

C++ 側で生成したバイナリを、例えば python の socket.send とかに渡したいとき。carrays でラップして、struct.pack/unpackで文字列化。もっと綺麗な方法ないかな……・

module hoge
%include "carrays.i"
%array_class(uint8_t, buffer)
import struct
buf = hoge.buffer(256)
hoge.f(buf.cast()) # C++側の定義はvoid f(uint8_t* buf)
s = struct.pack("256B", *[buf[i] for i in xrange(256)])