ctype拡張モジュール
Moriyoshi Koizumi <mozo@mozo.jp>
自己紹介
● はてな:moriyoshi
● twitter:moriyoshit
●
某研究機関で生物シミュレーションの研究をし
ています。
● 日々PythonとC++を書いてます!!
● 好きなテンプレート言語はPHPです!!!!
パーフェクトPHP出ました
月刊Python出ます
BeepLoudやってます!
はい
ctypes拡張モジュールとは
● Python 2.5より追加
● Thomas Heller作
● C言語で書かれた共有ライブラリをPythonから
利用するためのライブラリ
● 中身はlibffiのラッパー
● 複数のOSに対応
● といってもピンときませんよね...
C言語で書かれた共有ライブラリを
Pythonから利用するための
ライブラリ
それCythonでできるよ
● CythonはCython拡張を施されたPythonで書か
れたコードをCに変換する仕組み
● 生成されたCのコードをPythonのC拡張にコン
パイルしない限りは利用できない
● 開発にはCをコンパイル、リンクする環境が必
要
●
配布時にも、各プラットフォーム用のバイナリ
の準備が必要
ctypesなら?
● 純粋なPythonスクリプトからCの関数を呼び出
せる
– コンパイル不要
– 配布時のバイナリ同梱も不要
● プロトタイプ作成、C関数のテストコード作成
に威力を発揮
Show me what it looks like!
import ctypes
# 標準Cライブラリを読み込む
dll = ctypes.CDLL("/usr/lib/libSystem.B.dylib")
# ライブラリの関数を呼び出す
dll.printf("Hello, %s world!n", "bucho")
基本的な使い方
● ctypes.CDLL オブジェクトを、引数として共有
ライブラリ名を渡して生成
● ctypesオブジェクトの属性にアクセスすると、
C関数を呼び出すためのラッパー関数が自動的
に生成される
● ラッパー関数は普通のPythonの関数として扱え
る
● ラッパー関数に渡す引数は自動的にCの型に変
換される
デモ
値ラッパー
import ctypes
dll = ctypes.CDLL("/usr/lib/libSystem.B.dylib")
dll.printf("%gn", 3.14)
Traceback (most recent call last):
File <stdin>, line 3, in <module>
dll.printf("%gn", 3.14)
ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>:
Don't know how to convert parameter 2
実行結果
値ラッパー
import ctypes
dll = ctypes.CDLL("/usr/lib/libSystem.B.dylib")
dll.printf("%gn", ctypes.c_double(3.14))
3.14
実行結果
値ラッパー
● 組み込みのPythonの型とCの型は一対一で対応
していない
● Cの型に対応するPython型をctypes側で用意
● 明示的に型を指定してC関数を呼び出したい場
合は値ラッパーのオブジェクトを渡すと、最終
的に対応するCの型に変換される
値ラッパー
値ラッパークラス 対応するCの型
c_byte, c_ubyte, c_short,
c_ushort, c_int, c_uint,
c_long, c_ulong, c_longlong,
c_ulonglong
char, unsigned char, short,
unsigned short, int,
unsigned int, long, unsigned
long, long long, unsigned
long long
c_foat, c_double,
c_longdouble
foat, double, long double
c_char_p, c_wchar_p char *, wchar_t*
c_void_p void *
など
もうちょっと複雑な例
import ctypes
# 標準Cライブラリを読み込む
dll = ctypes.CDLL("/usr/lib/libSystem.B.dylib")
# ライブラリの関数を呼び出す
dll.getcwd.restype = ctypes.c_char_p
print dll.getcwd() # 現在の作業ディレクトリ
dll.sqrt.restype = ctypes.c_double
dll.sqrt.argtypes = (ctypes.c_double, )
print dll.sqrt(16) # 16の平方根
もうちょっと複雑な例
● C関数の戻り値の型は、デフォルトではint型で
あるとみなされる
● C関数のシグニチャを指定するときは、
ラッパー関数の以下の属性を指定する。
– restype
– argtypes
ポインタ渡し
import ctypes
dll =
ctypes.CDLL("/usr/lib/libSystem.B.dylib")
retval = ctypes.c_int()
dll.scanf("%d", ctypes.byref(retval))
print retval
ポインタ渡し
●
引数に指定されたポインタの示す先に戻り値を
返すようなC関数を扱う場合
● ctypes.byref()
ctypes.POINTER
●
任意の型のポインタ型を作る場合は
ctypes.POINTER(型) を呼ぶと、対応するポイ
ンタ型が作られる
● ctypes.POINTER(ctypes.c_int) → int *
ctypes.POINTER
import ctypes
c_int_p = ctypes.POINTER(ctypes.c_int)
dll =
ctypes.CDLL("/usr/lib/libSystem.B.dylib")
retval = ctypes.c_int()
dll.scanf("%d", c_int_p(retval))
print retval
※このケースだと、ctypes.byref() 使った方が早いです。
構造体
● ctypes.Structureクラスを継承したクラスを作る
ことで、Cの構造体に対応したラッパー型を作
れる
● _fields_ 属性に (フィールド名, 型) からなるタ
プルのリストを渡す
構造体
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
char *tm_zone;
long tm_gmtoff;
};
class TMStructure(ctypes.Structure):
_fields_ = [
('tm_sec', ctypes.c_int),
('tm_min', ctypes.c_int),
('tm_hour', ctypes.c_int),
('tm_mday', ctypes.c_int),
('tm_mon', ctypes.c_int),
('tm_year', ctypes.c_int),
('tm_wday', ctypes.c_int),
('tm_yday', ctypes.c_int),
('tm_isdst', ctypes.c_int),
('tm_zone', ctypes.c_char_p),
('tm_gmtoff', ctypes.c_long)]
コールバック関数
void call_callback(void(*cb)(const char
*))
{
cb("hoge");
}
import ctypes
dll = ctypes.CDLL("libcallback.dylib")
cfun = ctypes.CFUNCTYPE(None, ctypes.c_char_p)
def callback(string):
print "Hello, %s world!" % string
dll.call_callback(cfun(callback))
コールバック関数
● ctypes.CFUNCTYPE(戻り値の型, [引数の型, 引
数の型...]) を呼び出して、コールバック関数の
ラッパーオブジェクトを生成する
● ラッパーオブジェクトは、C関数の呼び出し時
に、関数ポインタに変換される
クロスプラットフォーム
● MacのPythonでも
● WindowsのPythonでも
● Free UnixのPythonでも
● それからIronPythonでも
複数プラットフォームを
サポートするときの注意点
● たとえば標準C関数のライブラリ名はプラット
フォームごとに違う
● sys.platform などでOSを判定して対処
まとめ
● dll = ctypes.CDLL()で読み込み
● dll.[関数名]() で関数を呼び出す
● 関数のシグニチャを指定したい場合はrestypeと
argtypes
● ラッパー型 c_*
● ポインタ渡しは ctypes.byref()
● 構造体は ctypes.Structure
● コールバック関数は ctypes.CFUNCTYPE()
ご清聴ありがとうございました
はい
始まって
しまいました
すべらない話
PSP®
Go
値下げしました
さて
P○P Go
○の中に
入る文字は?
1.H
2.S
3.P
はい
1. PHP
ですね
PHP Go
世の中
見渡せば
Pythonばかり
PHPに日の目を
はい
PHP in Python
プロジェクト始動
http://bitbucket.org/moriyoshi/php-in-python

More Related Content

PDF
MagicOnion入門
PDF
SSII2019企画: 画像および LiDAR を用いた自動走行に関する動向
PDF
MagicOnion~C#でゲームサーバを開発しよう~
PDF
STMとROSをシリアル通信させて移動ロボットを作る
PPTX
高速なソートアルゴリズムを書こう!!
PPT
メタプログラミングって何だろう
PDF
【Unity道場 建築スペシャル2】点群ビジュアライゼーション
PDF
ROS の活用による屋外の歩行者空間に適応した自律移動ロボットの開発
MagicOnion入門
SSII2019企画: 画像および LiDAR を用いた自動走行に関する動向
MagicOnion~C#でゲームサーバを開発しよう~
STMとROSをシリアル通信させて移動ロボットを作る
高速なソートアルゴリズムを書こう!!
メタプログラミングって何だろう
【Unity道場 建築スペシャル2】点群ビジュアライゼーション
ROS の活用による屋外の歩行者空間に適応した自律移動ロボットの開発

What's hot (20)

PPTX
Visual Studio CodeでRを使う
PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
PDF
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
PPTX
Kantocv 2-1-calibration publish
PDF
FridaによるAndroidアプリの動的解析とフッキングの基礎
PDF
Rust で RTOS を考える
PDF
Optimizer入門&最新動向
PPTX
ORB-SLAMの手法解説
PPTX
ARマーカーを用いた位置姿勢推定
PDF
ナレッジグラフ入門
PDF
シェル芸初心者によるシェル芸入門
PDF
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
PDF
ドメイン駆動設計をゲーム開発に活かす
PDF
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
PPTX
OpenAI FineTuning を試してみる
PDF
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
PDF
イミュータブルデータモデルの極意
PDF
Building the Game Server both API and Realtime via c#
PDF
基礎線形代数講座
PDF
Pythonによる黒魔術入門
Visual Studio CodeでRを使う
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
Kantocv 2-1-calibration publish
FridaによるAndroidアプリの動的解析とフッキングの基礎
Rust で RTOS を考える
Optimizer入門&最新動向
ORB-SLAMの手法解説
ARマーカーを用いた位置姿勢推定
ナレッジグラフ入門
シェル芸初心者によるシェル芸入門
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメイン駆動設計をゲーム開発に活かす
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
OpenAI FineTuning を試してみる
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
イミュータブルデータモデルの極意
Building the Game Server both API and Realtime via c#
基礎線形代数講座
Pythonによる黒魔術入門
Ad

Viewers also liked (6)

ODP
C Types - Extending Python
KEY
Chain of Responsibility
PDF
戦国時代を生きた「黒田官兵衛」とWeb時代を生きる「エンジニア」
PDF
Deep learning入門
PDF
Pythonで画像処理をやってみよう! 第1回 - ヒストグラムと濃度変換 -
PDF
ニコニコ生放送の配信基盤改善
C Types - Extending Python
Chain of Responsibility
戦国時代を生きた「黒田官兵衛」とWeb時代を生きる「エンジニア」
Deep learning入門
Pythonで画像処理をやってみよう! 第1回 - ヒストグラムと濃度変換 -
ニコニコ生放送の配信基盤改善
Ad

More from Moriyoshi Koizumi (20)

PDF
Goをカンストさせる話
PPTX
PHP7を魔改造した話
PPTX
Authentication, Authorization, OAuth, OpenID Connect and Pyramid
PDF
All I know about rsc.io/c2go
PPTX
HLSについて知っていることを話します
PPTX
Pyramidのrendererをカスタマイズする
PPTX
Hacking Go Compiler Internals / GoCon 2014 Autumn
PDF
Uguisudani
PDF
よいことも悪いこともぜんぶPHPが教えてくれた
PDF
Ik in action
PDF
PDF
Haxeについて
PDF
PDF
PHP language update 201211
PDF
mod_himoteからはじめよう
PDF
HPHPは約束の地なのか
PDF
Pyfes201110
PDF
Phjosh(仮)プロジェクト
PDF
Aaなゲームをjsで
PDF
Aaなゲームをjsで
Goをカンストさせる話
PHP7を魔改造した話
Authentication, Authorization, OAuth, OpenID Connect and Pyramid
All I know about rsc.io/c2go
HLSについて知っていることを話します
Pyramidのrendererをカスタマイズする
Hacking Go Compiler Internals / GoCon 2014 Autumn
Uguisudani
よいことも悪いこともぜんぶPHPが教えてくれた
Ik in action
Haxeについて
PHP language update 201211
mod_himoteからはじめよう
HPHPは約束の地なのか
Pyfes201110
Phjosh(仮)プロジェクト
Aaなゲームをjsで
Aaなゲームをjsで

ctypes拡張モジュール