ctypes
是您快速完成它的最佳选择,并且很高兴与您一起工作,因为您仍在编写 Python!
我最近包装了一个FTDI驱动程序,用于使用 ctypes 与 USB 芯片进行通信,它很棒。我在不到一个工作日的时间内完成了所有工作。(我只实现了我们需要的功能,大概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
有人对各种选项进行了一些基准测试。
如果我必须用大量的类/模板/等包装一个 C++ 库,我可能会更犹豫。但是 ctypes 与结构配合得很好,甚至可以回调到 Python 中。