Blanktar

  1. top
  2. blog
  3. 2013
  4. 05

pythonのモジュールをC言語から使う

pythonで書かれたモジュールをC言語から使うってのを試してみた話。

まあ、つまり、前に書いたpython/C APIの逆のことね。 正直使いどころはちょっとわからないけれど、まあいいじゃない。

準備する

Python.hってのをインクルードする必要があるので、その辺を準備します。 ていっても、pythonがインストールされてる環境ならすでに入っているはず。

インクルードパスにpythonがインストールされているディレクトリにあるincludeってパスを追加。 それと、libs/python27.libってファイルを一緒にコンパイルしてやります。 環境/バージョンによってファイル名違うかもだけど、適当に。

windows / Visual C++のclコマンド を使う場合は

$ cl *.c /I%PYTHON_DIR%¥include %PYTHON_DIR%¥libs¥python27.lib

みたいな感じで。

勿論、%PYTHON_DIR%ってやつはpythonのインストールディレクトリに置き換えてください。

動かしてみる

#include <Python.h>
int main()
{
Py_Initialize();
PyRun_SimpleString("print 'hello, world!'");
Py_Finalize();
return 0;
}

こうすると、

$ python -c "print 'hello, world!'"

ってしたのと同じになります。

pythonのコードをインポートして、関数を実行

いよいよ本命、pythonで書いたモジュールを使ってみます。 エラー処理とか省いて書いてるので、そのへんは適当に追加してね。

#include <stdio.h>
#include <Python.h>
int main()
{
PyObject *pModule, *pTmp;
char *sTmp;
Py_Initialize();
/* モジュールをimport */
pModule = PyImport_ImportModule("script");
/* pythonで言う pTmp = getattr(pModule, 'func')() みたいな。 */
pTmp = PyObject_CallMethod(pModule, "func", NULL);
/* PyObjectをC言語の型に変換 */
PyArg_Parse(pTmp, "s", &sTmp)
printf("%s¥n", sTmp);
Py_Finalize();
return 0;
}

こんな感じ。

python側のコードは

def func():
print 'this printed by python'
return 'and, this printed by C'

みたいにしといてください。

コンパイルして実行してみると、pythonに書いた2つの文が両方表示されるはず。

参考: 超高レベルレイヤ - Python 2.7ja1 documentation