C の関数を呼び出す

このチュートリアルでは、Cython のコードから C のライブラリ関数を呼び出 す上で知っておく必要のあることを簡単に解説します。外部の C ライブラリ を使い、ライブラリをラップしたりエラーを処理したりする方法を、長めに、 より詳しく解説したチュートリアルは、 C ライブラリを使う にあります。

簡単のために、標準の C ライブラリの使い方から初めましょう。コードを実 行する上で他に依存ファイルが必要なく、何より Cython はこの手の関数に対 する宣言をたくさん持っているという利点があるからです。 というわけで、まずは cimport して使うだけです。

例えば、低水準の方法を使って、 char* の値から数値をパースしたいと しましょう。 stdlib.h に入っている atoi() 関数を使えます。 コードは以下のようになります:

from libc.stdlib cimport atoi

cdef parse_charptr_to_py_int(char* s):
    assert s is not NULL, "byte string value is NULL"
    return atoi(s)   # 注意: atoi() にはエラー検出機能がありません!

標準で cimport できるファイルの一覧は、 Cython のソースパッケージの Cython/Includes/ の下を見れば分かります。この中には、 CPython の C-API に関する宣言もひと通り入っています。例えば、 C のコンパイル時に、 どのバージョンの CPython が使われているかを知りたければ、以下のように します:

from cpython.version cimport PY_VERSION_HEX

print PY_VERSION_HEX >= 0x030200F0 # Python version >= 3.2 final

Cython は、 C の数学ライブラリに対する宣言も提供しています:

from libc.math cimport sin

cdef double f(double x):
    return sin(x*x)

ただし、Linux のような一部の Unix ライクのシステムは、数学ライブラリを デフォルトでリンクしないので、宣言を cimport するだけでなく、ビルドシ ステム上で共有ライブラリ m へのリンクを設定せねばなりません。 distutils を使うなら、 Extension() セットアップの libraries パラメタに m を追加します:

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

ext_modules=[
    Extension("demo",
              ["demo.pyx"],
              libraries=["m"]) # Unix-like specific
]

setup(
  name = "Demos",
  cmdclass = {"build_ext": build_ext},
  ext_modules = ext_modules
)

利用可能な形の宣言が Cython で提供されていないような C コードへのアク セスを行いたいなら、自分で宣言する必要があります。例えば、上の sin() 関数は、以下のように定義されています:

cdef extern from "math.h":
    double sin(double)

この宣言は、 sin() 関数を Cython コード中で使えるようにすると同時 に、 math.h ヘッダファイルを含んだ C のコードを生成するように Cython に指示します。これで C コンパイラはコンパイル時に math.h の オリジナルの宣言を見に行くようになります。一方、 Cython は “math.h” ヘッダファイルを解釈しないので、別に定義を持っておく必要があるのです。

数学ライブラリの sin() 関数と同様、どんな C のライブラリでも、 Cython が生成するモジュールから共有あるいは静的ライブラリをリンクでき るかぎり、宣言を作成して呼び出せます。

Previous topic

チュートリアル

Next topic

C ライブラリを使う

This Page