如何使用 ctypes 在 python 中正确包装 C API?

Posted

技术标签:

【中文标题】如何使用 ctypes 在 python 中正确包装 C API?【英文标题】:how to properly wrap C API in python using ctypes? 【发布时间】:2017-07-07 21:04:57 【问题描述】:

我使用 ctypes 在 Python 中封装了来自 C 库的两个 API。一个有效,另一个无效。我的问题是:如何使用 ctypes 从 Python 中的 C 库中正确包装 API?

一些背景信息:

import ctypes 
from ctypes import *

MF = (b'path_to_file') 
beginTime = (-Value)
endTime = (Value)
PN = (b'path_to_String')
DT_RETURNGMT = 0x0100
DT_FLOAT = 0x0001
convert = DT_RETURNGMT|DT_FLOAT

这个有效:

#read functions
dll.openFile.argtypes = c_char_p,
dll.openFile.restype = POINTER(File)

dll.freeFile.argtypes = POINTER(File),
dll.freeFile.restype = None
f = dll.openFile(MF)
print(f[0].fileInfo[0].items)

这个没有:

#retrieve data
dll.readSP.argtypes = POINTER(File), c_char_p(PN), 
c_double(beginTime), c_double(endTime),
0, 0, 
c_ushort(convert),
dll.readSP.restype = POINTER(SP)
#pointer to the SP file structure 
g = dll.readSP(f, MF)
print(g)
print(g[0].points)
pint(g[0].tStamp[0].data[0].TTag)

我认为指针是正确的,因为当我告诉代码 print(g) 时,它会返回我的 SP 对象的位置,如下所示:

<__main__.LP_SP object at 0x000001D1EAB862C8>

但它不能返回 SP 文件结构中其他任何内容的位置。这让我相信问题在于我如何包装 API。但我不确定我哪里出错了。

我认为我一定没有正确包装 API,但我不确定我哪里出错了。 double *refTIME 和 struct TimeTage *refGMT 在 C 代码中为 NULL,因此我在脚本中将它们设为 0。

【问题讨论】:

File 是如何定义的? 在似乎打算作为一个语句的中间的所有这些换行符是怎么回事? 或者他们不打算成为一个声明?再看一遍,它们作为一个陈述或其他任何东西真的没有多大意义。 dll.readSP.argtypes = POINTER(File), c_char_p(PN),dll.readSP.restype = POINTER(SP) 之间的那些东西应该是什么? 【参考方案1】:

您在非工作代码中定义了 instances 而不是 types。而不是:

dll.readSP.argtypes = POINTER(File), c_char_p(PN), c_double(beginTime), c_double(endTime), 0, 0, c_ushort(convert),

你需要:

dll.readSP.argtypes = POINTER(File), c_char_p, c_double, c_double, c_double, POINTER(TTag), c_ushort

【讨论】:

谢谢,我认为这是问题所在,但我不确定。所以你的回答解决了我遇到的一个问题,但现在我在调用 dll 时遇到错误。我收到TypeError this function takes at least 2 arguments (1 given) 当我调用 dll 时发生此错误,调用看起来像这样g = readSP(MF) 参数到底是什么意思? @101 文件的定义如下(为方便起见缩短):class File(Structure): _fields_ = [ ('name', ctypes.c_char_p), ('header', ctypes.POINTER(Header)), ('FInfo', ctypes.POINTER(FInfo)), 参数是函数调用括号内的值,例如MF 是您的第一个也是唯一的论点。它期待另一个。您是否有指向您正在调用的 DLL 文档的链接?

以上是关于如何使用 ctypes 在 python 中正确包装 C API?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ctypes 将数组从 C++ 函数返回到 Python

Python 和 ctypes:如何正确地将“指针对指针”传递给 DLL?

我是不是正确使用 ctypes 来对这个结构进行 python 化?

如何使用ctypes,python将字符串参数传递给C++函数

通过 ctypes 从 Python 调用的 C 函数返回不正确的值

如何使用 ctypes 在 python 中查看指针值的变化