niitsuma blog このページをアンテナに追加 RSSフィード

2008-02-09 python関係

[][]pythonc++インターフェイスの比較 swig boost.python ctypes

pythonc++インターフェイスを作る方法には

  1. boost.pythonを使う方法
  2. swigを使う方法
  3. python.ctypesを使う方法
  4. f2py (Fortranを使うためのInterface)を使う方法
  5. pyreを使う方法
  6. 直接Cのインターフェイスを作る方法

があるようだ。

http://www.scipy.org/Cookbook のUsing NumPy With Other Languages のセクションにさらに詳しい解説がある。

 ここでは特に配列(numpyの行列)をc++と連携して使う方法に注目していくつかの方法を比較する。numpyは数値計算や行列演算を行うpythonのパッケージでnumarrayの後継にあたる。numpyはnumarayと違って行列が配列の先頭ポインター(double *array)を渡すだけでc++とやりとりができる。そのためc++との連携で様々なメリットがある。

 以下にも類似した比較等の議論がある

  1. http://tasuku.suenaga.name/pub/pytc/Python-unconference01-cextension.pdf
  2. http://language-binding.net/

boost.python

boost.pythonを使う方法はubuntu7.10の場合は $ sudo apt-get install libboost-python とすることで導入できる。使い方は以前ここ

http://d.hatena.ne.jp/niitsuma/20080108/1199769332

に書いた。この方法のメリットは

  1. pythonからc++呼べるだけでなく、逆にc++からpythonのprogramを呼び出せる. 以下は詳しい使い方を解説しているサイトへのリンク
    1. http://d.hatena.ne.jp/Wacky/20060103/1136292735 : boost.pythonだけでなくswigの解説もある。わかりやすいexample codeもある
    2. http://d.hatena.ne.jp/kikuty/20080110 : c++からpythonboost.pythonで呼び出す方法の解説。関連するVisual Studioの設定の話題など。あまりわかりやくすない。
    3. http://www.boost.org/libs/python/doc/tutorial/doc/html/python/embedding.html boost本家の解説
    4. 関連
      1. http://wiki.python.org/moin/boost.python/EmbeddingPython 
      2. http://www.boost.org/libs/python/doc/v2/exec.html
      3. http://www.boost.org/libs/python/doc/v2/import.html
      4. http://www.boost.org/libs/python/doc/v2/callbacks.html
  2. c++classpythonに渡せる
    1. http://python.matrix.jp/tips/cpp_extension.html
    2. http://www.boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html

デメリットは

  1. numpyにまだ対応していない
  2. c++のコードを改変しないといけない(boost.pythonのヘッダーを追加したりする)

がある。

boost.pythonインターフェイスを生成する作業を自動化するPy++というtoolもある。しかし試したところ、この自動化toolは複雑なc++のコードでは動かないようだ。

 現在のboostはnumarrayには対応しているがnumpyには対応していない。以下のサイトの方法でnumpyの配列(行列)をc++に渡すことができるらしいがubuntu7.10の環境では動かなかった。

http://www.eos.ubc.ca/research/clouds/software/pythonlibs/num_util/num_util_release2/

(誰か動かせた人がいたら環境の情報など教えていただけると幸せです)

boost.ublasのインターフェイスも書かれているようだ

http://mail.python.org/pipermail/c++-sig/2006-December/011719.html

swig

swigの生成するwrapperファイル hoge_wrapper.cとwrapしたいhoge.cを一緒にコンパイルするだけですむので、既存c++libraryをpythonに移殖するには向いていると思われる。しかし,少し複雑なc++のコードになると扱うことができない。(複雑なc++コードをwrapするために http://www.itk.org/HTML/CableSwig.html こんなものもあるようだ. cableswigについては別記事cable swigを書いた)

std::vectorなど様々なc++要素に対するインターフェイスが用意されている。c++classpythonから呼ぶこともできる.classの呼び方は以下

  1. http://www.geocities.com/foetsch/python/extending_python.htm#example 短いexmaple codeで使い方がすぐわかる
  2. http://www.swig.org/Doc1.3/Python.html#Python_nn20 同じくswig本家の example code.こちらもわかりやすい.

boost.pythonと異なりc++から逆にpythonのコードは呼び出せない。

numpyに対応している。numpy/docs/swig にあるnumpy.iファイル(ubuntu7.10の場合は /usr/share/doc/python-numpy/swig/numpy.i.gz )を使ってhttp://projects.scipy.org/scipy/numpy/browser/trunk/numpy/doc/swig/doc/numpy_swig.html?format=raw の方法を実行すればよいらしい。swigの使い方はサンプルコードの通りにまねすればいいだけなので簡単だ。ただし計算速度が遅くなるとswigのサイトには書いてあった。googleではswigが使われているそうだhttp://www.atransia.co.jp/home/fukamachi/Diary/2006/02/12/

ctypes

c++から呼ぶためのdllやshared libをpythonからも呼んでしまう方法。boost.pythonと異なりc++から逆にpythonのコードは呼び出せない。swigと異なりcのコードに手を加えるのではなく呼び出すpythonの側でいろいろと手間を追加する方法だ。使い方を学習する手間はswigと同程度。(次versionのpythonであるpython3.0にもctypesはあるようだ )ctypes一般の使い方は以下のサイトが参考になるになる

  1. http://newcamel.logos.ic.i.u-tokyo.ac.jp/~s1s5/pukiwiki/index.php?programming%2Fpython%2Fctypes
  2. http://blog.goo.ne.jp/anoydevl/e/a1193ca3cafed036c8c232ac4a14d894 工夫してclassをctypsから呼ぶ方法
  3. ctypes tutorial

linuxの場合はこんな風に使う

import ctypes
libc = ctypes.cdll['/lib/libc.so.6']
name = "John Doe"
libc.printf("Hello, %s!\n", name) 

windowsの場合は,

from ctypes import windll
windll.user32.MessageBoxW( 0, u"テスト", 0, 0 )

のように使う.windowsの場合のより詳しい使い方は http://mtamaki.com/trac/mtamaki/ticket/47

以下のようにしてstructを扱うこともできるようだ.

struct svm_node {
    int index;
    double value;
};
from ctypes import Structure, c_int, c_double
class svm_node(Structure):
    _fields_ = [('index', c_int), ('value', c_double)] 

関数や構造体の呼び出しはできるがstd::vectorc++classpythonから呼ぶ方法は見つけられなかった(ここで工夫してclassを扱う方法も解説している)。

 numpyも使える。numpyの行列(配列)を使う方法は

http://www.scipy.org/Cookbook/Ctypes

に書いてある。

OpenCVと組み合わせてnumpyも使う場合にswigとctypesのどちらが良いかの議論ここでされている。結論としてはOpenCVと組み合わせる場合はctypesがいいということのようだ。同様の使い方をctypesでする場合の話題がここにまとめられている。

直接cのインターフェイスを書く

http://projects.scipy.org/scipy/numpy/wiki/NumPyCAPI

に書いてる方法でできるようだ。

結論

boost.pythonがnumpyに対応してくれるなら一番うれしい.swigは複雑なコードを変換できないため手で修正する必要があるためおすすめできない。ctypesも良いがclassやstd::vectorを直接pythonから呼び出す方法をみつけられなかった。もしあるならばctypesを使いたい。次期バージョンのpythonであるpython3.0にctypesがあるので後のことを考えるとctypesもいいのかもしれない。


cからpythonを呼びだす方法

embedding で検索すると必要な情報がでてくる

artkartk 2008/11/15 21:17 こんにちはartkです.
http://arataka.wordpress.comでブログ書いてます.リンクありがとうございます.

C++に特化してるわけではありませんが,pythonのc/c++との連携は Python Scripting for Computational Science(http://folk.uio.no/hpl/scripting/)が詳しいです.ご存知かもしれませんが,お勧めです.私もかなり参考にしました.

Springerのオンライン文章がダウンロードできる環境(大学とか)なら検索するとそこから全部ダウンロードできてしまいます.

niitsumaniitsuma 2009/02/06 12:03 コメントありがとうございます。返信が遅れすみません。非常に参考になる書籍をありがとうございます。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証