18
20

More than 5 years have passed since last update.

CをPythonから使えるようにCythonでwrapする

Last updated at Posted at 2015-07-29

「Cython Cとの融合によるPythonの高速化」オライリーから
C言語で書かれた関数をPythonでimportして実行できることをUbuntu上でたどってみた。

まずは、この本のサンプルがgithub上にあるのでzipファイルでまとめてダウンロードする。
https://github.com/cythonbook/examples

展開してできたディレクトリに移動する。
examples-master/07-wrapping-c/01-wrapping-c-functions-mt-random

ここにはMakefileがあるのでmakeしてみる。
そうすると必要なファイルができたようで
同書p128にある例がIPythonから動作する。
In [1]: import mt_random

In [2]: mt_random.init_state(42)

In [3]: mt_random.rand()
Out[3]: 0.37454011439684315

確かに、本に書かれているようにCythonでC関数をラップできている。

まず、Cのソースファイルとヘッダファイルとがあること。

Cythonにおける外部Cコードの宣言(拡張子 .pxd)

mt.pxd
cdef extern from "mt19937ar.h":
    void init_genrand(unsigned long s)
    double genrand_real1()

C関数のラップ(拡張子 .pyx)

mt_random.pyx
# distutils: sources=["mt19937ar.c"]
cimport mt

def init_state(unsigned long s):
    mt.init_genrand(s)

def rand():
    return mt.genrand_real1()

コンパイルの方法を指示するsetup.pyファイル

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

ext = Extension("mt_random",
                sources=["mt_random.pyx", "mt19937ar.c"])

setup(name="mersenne_random",
      ext_modules = cythonize([ext]))

そしてsetup.pyを実行するMakefileが既にzipファイルの中に含まれていた。
これをmakeすれば先ほどの実行結果になりました。

pxdファイル, pyxファイル, setup.pyを書くことでwrapできることがわかりました。

このようにして実装したmt_randomモジュールについて
help(mt_random)
とすると
以下のようにhelpが表示されるのも便利です。

Help on module mt_random:
NAME
mt_random

FILE
/(略)/examples-master/07-wrapping-c/01-wrapping-c-functions-mt-random/mt_random.so

FUNCTIONS
init_state(...)

rand(...)

DATA
test = {}

この例題以上のことを理解するには、同書の7章を読むことのようです。

全てをC言語で書かなくても、ボトルネック部分だけをC言語で書いて
Cythonを使ってラッパーを書けば十分になるというのはうれしい限りです。

18
20
1

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
18
20