是您最好的選擇,因爲它可以快速完成任務,並且很高興與您一起編寫Python!
我最近用ctypes封裝了一個用於與USB芯片通信的驅動程序FTDI,它非常棒。我已經完成了這一切,並在不到一個工作日的工作。 (我只實現了我們需要的功能,大約15個功能)。
我們以前使用第三方模塊PyUSB出於同樣的目的。 PyUSB是一個實際的C/Python擴展模塊。但是PyUSB在阻止讀/寫操作時沒有釋放GIL,這對我們造成了問題。所以我使用ctypes編寫了我們自己的模塊,它在調用本機函數時釋放GIL。
有一點要注意的是,ctypes不會知道#define
常量和你正在使用的庫中的東西,只有函數,所以你必須在你自己的代碼中重新定義這些常量。
這裏的代碼怎麼會找一個例子(手剪斷了,只是想向你展示它的要點):
from ctypes import *
d2xx = WinDLL('ftd2xx')
OK = 0
INVALID_HANDLE = 1
DEVICE_NOT_FOUND = 2
DEVICE_NOT_OPENED = 3
...
def openEx(serial):
serial = create_string_buffer(serial)
handle = c_int()
if d2xx.FT_OpenEx(serial, OPEN_BY_SERIAL_NUMBER, byref(handle)) == OK:
return Handle(handle.value)
raise D2XXException
class Handle(object):
def __init__(self, handle):
self.handle = handle
...
def read(self, bytes):
buffer = create_string_buffer(bytes)
count = c_int()
if d2xx.FT_Read(self.handle, buffer, bytes, byref(count)) == OK:
return buffer.raw[:count.value]
raise D2XXException
def write(self, data):
buffer = create_string_buffer(data)
count = c_int()
bytes = len(data)
if d2xx.FT_Write(self.handle, buffer, bytes, byref(count)) == OK:
return count.value
raise D2XXException
有人做了各種選項some benchmarks。
如果我不得不用大量的classes/templates/etc包裝一個C++庫,我可能會更猶豫。但是ctypes可以很好地適用於Python,甚至可以在Python中使用callback。
在一定程度上,具體應用參與(圖書館做什麼)可能會影響方法的選擇。我們已經非常成功地使用ctypes來與供應商提供的各種硬件(例如示波器)DLL進行對話,但由於與Cython或SWIG相比額外的開銷,我不一定會選擇ctypes來與數字處理庫交談。 – 2009-12-21 21:07:06
現在你有什麼你在找什麼。四個不同的答案(有人也發現了SWIG)。這意味着,現在你有4個選擇,而不是3 – 2009-12-22 06:57:19
@ralu這就是我想要的:-)但嚴重的是,我沒有期望(或想)一個贊成/反對錶或一個單一的答案說:「這是你需要做」。任何有關決策的問題最好由每個可能選擇的「粉絲」回答他們的理由。然後社區投票就像我自己的工作一樣(查看論點,將它們應用到我的案例中,閱讀提供的源文件等)。長話短說:這裏有一些很好的答案。 – balpha 2009-12-22 08:10:08