python - 我是否正确使用 ctypes 来 pythonify 这个结构?

标签 python c++ c dll ctypes

我正在尝试与 this DLL 通话使用 python 的 ctypes。许多函数采用或返回 HGRABBER 类型:

typedef struct HGRABBER_t__ { int unused; } HGRABBER_t;
#define HGRABBER HGRABBER_t* 

(完整的头文件可以查看here)。下面是一个返回 HGRABBER 类型的函数原型(prototype)示例:

HGRABBER __stdcall IC_CreateGrabber();

这是我在 python 中实现此结构并使用它从 DLL 调用该函数的尝试:

import ctypes as C
class GrabberHandle(C.Structure):
    _fields_ = [('unused', C.c_int)]

dll = C.windll.LoadLibrary('tisgrabber_x64.dll')
dll.create_grabber = dll.IC_CreateGrabber
dll.create_grabber.argtypes = []
dll.create_grabber.restype = GrabberHandle
my_handle = dll.create_grabber()

这似乎可行,但我担心我做错了。我没有使用 C 语言的经验,而且我不认为我理解定义 HGRABBER 类型的 typedef#define 语句。 我是否正确调用了 IC_CreateGrabber我是否应该将 GrabberHandle 定义为指向结构的指针,而不是结构?

感谢阅读,如果我能以某种方式澄清我的问题,请告诉我。

最佳答案

你是对的,你实际上想要一个指向 StructurePOINTER,而不是 Structure 本身。

将 C 语言翻译成英语,非常松散(如果您尝试学习 C 语言会很危险,但对于使用 ctypes 来说已经足够好了):

  • struct 定义了一个名为 struct HGRABBER_t__ 的类型,它是一个包含一个 int 的结构。
  • typedef 定义了一个名为 HGRABBER_t 的类型,作为 struct HGRABBER_t__ 的同义词。
  • #define 将名为 HGRABBER 的类型定义为指向 HGRABBER_t 的指针。

因此,您的 GrabberHandle 等同于 HGRABBER_tHGRABBER 的等价物是:

GrabberHandlePtr = C.POINTER(GrabberHandle)

所以你想要这个:

dll.create_grabber.restype = GrabberHandlePtr

可能很难调试差异。一个只包含 int 的 C 结构看起来与内存中的 int 相同。在 Win32 上,int 和指针都是 32 位值。而一个名为 unused 的 int 可能充满了无意义的垃圾,因此很难将它与您不小心将其视为 int 的指针区分开来。所以一切看起来都很好,直到您稍后在代码中出现段错误 30 行并且不知道出了什么问题。 :)

关于python - 我是否正确使用 ctypes 来 pythonify 这个结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25818697/

相关文章:

C++:将 __PRETTY_FUNCTION__ 附加到 c 字符串

c - 为什么我们向 scanf 提供地址?

python - 查找键以相同前缀开头的字典值的更有效方法

python - 将 python 脚本 TBA SHA1 更改为 SHA256

python - Pandas:根据组进行不同的聚合

c - 用GTK查询光标位置

c - 您将如何使用函数来计算电阻器阵列的电流和电压?

python - pip:根据包名称选择索引url?

微分求解器上的 C++ 段错误

c++ - 覆盖 QIODevice 子类中的 readData 返回不正确的结果