#本日は
C/C++ から Pythonを呼ぶ方法としてCythonを使う方法を紹介です.
高速化のためにPythonで外堀を書いてCoreな部分をC/C++ということをするというのはよくあります.今回はその逆です.逆のって公式ドキュメント以外あまりてがかりがないのよね・・・.ありましたら教えてくださいましOTL.
(追記:Mac版書きました.)
環境
- OSはVisual Studio を使うためWindowsを用います.
- IDE Visual Studio 2017 Community
- 特にCommunity, 2017で限る必要はないです.2013でも行けたので2015でもOKだと思います.
- Python3.5.4(Miniconda3)
- Cython 0.26
Visual Studioによる環境作成
ソルーション作成
Visual C++ -> 空のプロジェクトを選択->とりあえずOKボタンを押す.これで空のプロジェクトを生成できます.ソルーションおよび最初に作られるプロジェクト名はProject1となっています.
ソースファイルにコードを追加
Ctrl+Shift+Aで空のC++ファイルを追加.デフォルト名はSource.cppとなっていますが,そのまま使用.
後でSource.cppにコードを書いていきます.いまは白紙のままで放置します.
Python の場所を知る
ここからは各自の環境依存になるので注意です.
読者はPythonをよく使っている方だと思うので自分がどのPythonを使っているかはご存知だと思います.とはいえ,確認してみましょう.
コマンドプロンプトを開いて
> where python
を実行します.私の場合はC:\ProgramData\Miniconda3\python.exe
でした.
C:\ProgramData\Miniconda3
に移動しましょう.
下の写真では include
と libs
を選択しています.
このディレクトリのパスを次に使うのでメモしておいてください.
プロパティ編集
プロパティー>VC++ディレクトリー>インクルードディレクトリに上でメモしたincludeのフルパスを追加.
私の場合は C:\ProgramData\Miniconda3\include
です.
プロパティー>VC++ディレクトリー>インクルードディレクトリに上でメモしたlibsのフルパスを追加.
私の場合は C:\ProgramData\Miniconda3\libs
です.
下の図で囲んだ赤枠のようにしましょう.
あと,プラットフォームはx64にしておきます.
debug binaries, debugging symbols の導入
公式のPythonのホームページからインストーラをゲットしてインストーラーを起動します.
Customize installationをクリックしてNextボタンをクリック.
download debug binaries, debugging symbols にチェックを入れます.
このPythonをメインに用いない場合はPATHの追加は不要です.
ビルドチェック
Source.cppに次を記述
#include<Python.h>
int main() {
Py_Initialize();
printf("Hello");
Py_Finalize();
return 0;
}
releaseモードでビルド出来たらひとまずOK.Python.hがないよーとか怒られたらインクルードディレクトリの追加が失敗しています.落ち着いて設定しなおしましょう.
そしてデバッグモードではpython35_d.libと同名のDLLなるものが必要なのでそれを入手する必要があります.
上記のスタックオーバーフローを参考にPython公式ページからPython3のインストーラーを起動してオプションで"download debug binaries"を選択すると入手できます.探してみましょう.
Cythonコード作成
上で作成したSource.cppと同階層に次を作ります.
- setup.py
- cytest.pyx
各々のコードは次の通りです.
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("cytest.pyx"))
from libc.stdio cimport printf
cdef public struct Point:
double x
double y
cdef public Point DoubleCoord(Point p):
cdef Point q
q.x=2*p.x
q.y=2*q.x
printf("q.x=%f, q.y=%f\n",q.x,q.y)
return q
とりあえず頂点構造体を定義して座標を2倍にして返す関数をCythonで作りました.
setup
コマンドプロンプトを開いてCythonコードをビルドしましょう.
> python setup.py build_ext --inplace
生成コード追加
このときに生成される
cytest.c cytest.hをVisual Studioのソースファイルとヘッダーファイルに各々追加します.
Source.cpp 編集
#include<Python.h>
#include<stdio.h>
#include "cytest.h"
int main() {
Py_Initialize();
struct Point p;
p.x = 3.5;
p.y = 7.0;
struct Point q = DoubleCoord(p);
printf("q.x=%f,q.y=%f", q.x, q.y);
Py_Finalize();
}
ここまでの成果物としてVisual Studio上では下図のようになっているはずです.
実行すると次のようになります.
最後に
大変だーね・・・.
リファレンスとして
- [Interfacing with External C Code]
(http://cython.readthedocs.io/en/latest/src/userguide/external_C_code.html)
を挙げておきます.