LoginSignup
12
12

More than 5 years have passed since last update.

C/C++ から Cython によって生成されたコードを呼び出す(Windows版)

Last updated at Posted at 2017-11-11

本日は

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による環境作成

ソルーション作成

project.png

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に移動しましょう.
下の写真では includelibs を選択しています.
pythonhome.png

このディレクトリのパスを次に使うのでメモしておいてください.

プロパティ編集

プロパティー>VC++ディレクトリー>インクルードディレクトリに上でメモしたincludeのフルパスを追加.
私の場合は C:\ProgramData\Miniconda3\include
です.

プロパティー>VC++ディレクトリー>インクルードディレクトリに上でメモしたlibsのフルパスを追加.
私の場合は C:\ProgramData\Miniconda3\libs
です.

下の図で囲んだ赤枠のようにしましょう.
あと,プラットフォームはx64にしておきます.

propety.png

debug binaries, debugging symbols の導入

公式のPythonのホームページからインストーラをゲットしてインストーラーを起動します.
Customize installationをクリックしてNextボタンをクリック.
install.png
next.png
debug.png

download debug binaries, debugging symbols にチェックを入れます.
このPythonをメインに用いない場合はPATHの追加は不要です.

ビルドチェック

Source.cppに次を記述

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

各々のコードは次の通りです.

setup.py
from distutils.core import setup 
from Cython.Build import cythonize

setup(ext_modules=cythonize("cytest.pyx"))
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 編集

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上では下図のようになっているはずです.

vstotal.png

実行すると次のようになります.

result.png

最後に

大変だーね・・・.
リファレンスとして

を挙げておきます.

12
12
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12