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 時点)
- Python が落ちる
セグフォ的な、一番こまるやつ。自分の手元では 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)])