モブ沢工房

プログラミングとかLinux関連(特にOSSのグラフィックツール関連)とかレトロゲームとか3Dプリンタやら日曜大工等、色々。

SWIG関数にctypesからアクセス

ついでにこれも思いついたシリーズ。

すなわち例えば、SWIG側の内部にstaticで構造体ポインタのリストを持っておき。 idx = register_hogehoge(void *ptr)でそのリストに登録。 その後はidxを使って(OpenGLのテクスチャの名前みたいな感じで)、例えば draw_bg(idx, 0, 0) みたいなことをすると。まぁ、これだとオブジェクトが削除されたのを知るのは難しそうなので、そのへん十分に気を使って、と。 どうにかすればctypesのオブジェクトにincref的なことができるのかもですが、まだよく分かっておりません。 あ、ていうかよく考えると表面はPyObjectだろうから普通に行けちゃったりするのかな…

ともかく、そういういうことを思いついたのでやってみました。 特に普通の共有ライブラリと違う点もなく、簡単にできました…ポイントは * ctypesの名前関係が難しくなるのでextern "C" でその場を凌ぐ * void*だと、構造体を引数に入れただけだと自動変換してくれないっぽいので、pointer(obj)を使う * つかcast(pointer(obj), c_void_p)が正しい? まぁLinuxだから簡単だったのかも知れないですけどね。

その他、ctypesの関数にSWIG内から…というのも妄想していましたが、よくよく考えると上記の「SWIGをctypesで呼ぶ」作戦のほうが柔軟性も自由度も高そうなので、とりあえずこれでいいかなと。

最初に思いついたのはctypesでポインタをlongにする関数を作って呼び出し、SWIGでそのlong値を受けてそれを強引に構造体ポインタにキャストする…というものでした。実際に動いたのですが、実になんかその…ダサいというか無理矢理感が強すぎたので上記の方法を考えました。

もしかするとswigに直接ctypesの構造体のアドレスをvoid*ポインタとして送り込めるのかもですが、そのへん全然わからないのでした。