LoginSignup
29
23

More than 5 years have passed since last update.

Python3からC++の関数を呼び出す

Last updated at Posted at 2017-02-14

はじめに

Pythonは書きやすいけど速度が残念…
ということで、一部をC++で書き直してPythonから呼び出そうとしたんですが新しめの情報が少なかったのでまとめておきます。
Cythonを利用しますが、Cythonの導入やC++のコンパイラの導入などは解説しないので、他記事を参照してください。

例としてC++で足し算を行うadd_cという関数を作り、それをPythonから使ってみます。

C++側

Pythonから使うために特別な書き方をする必要はなく普通に書きます。

calc_c.hpp
#ifndef __GUARD
#define __GUARD

int add_c(int x, int y);

#endif

calc_c.cpp
#include "calc_c.hpp"

int add_c(int x, int y){
    return x + y;
}

Python側

直接PythonからC++の関数を呼ばずに、Cythonを経由して型の情報をつけてからC++の関数を呼びます。

calc.pyx
cdef extern from "calc_c.hpp":    #使いたい関数を含むC++のヘッダーを指定する
    cdef int add_c(int x, int y)  #使いたい関数を宣言する

#C++の関数を型情報をつけて呼び出すラッパー関数
def add(int x, int y):
    cdef int ans
    ans = add_c(x, y)
    return ans

コンパイル

calc.pyxをコンパイルするための設定ファイルを書きます。

setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

#コンパイルするソースファイルをリストで指定
source = [
    'calc_c.cpp',
    './calc.pyx'
    ]

setup(
    cmdclass = dict(build_ext = build_ext),
    ext_modules = [
        Extension(
            'calc',             #この名前でimportできるようになる
            source,
            language='c++',     #C++でコンパイルするために必要
        )
    ]
)

以下のコマンドを実行するとコンパイルが実行されて、共有ライブラリ(拡張子:so)ができます。

$ python3 setup.py build_ext

使ってみる

コンパイルして作った共有ライブラリを同階層に置いておけばimportで読み込めます。

main.py
import calc

print(calc.add(1, 1))

注意

C++側の関数名とCython側の関数名が被っているとコンパイルに失敗します。

29
23
0

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
29
23