简体   繁体   English

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

[英]Am I using ctypes correctly to pythonify this struct?

I'm trying to talk to this DLL using python's ctypes. 我正在尝试使用python的ctypes与这个DLL对话。 Many of the functions take or return an HGRABBER type: 许多函数采用或返回HGRABBER类型:

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

(the full header file can be viewed here ). (可在此处查看完整的头文件)。 Here's an example of a function prototype that returns an HGRABBER type: 这是一个返回HGRABBER类型的函数原型的HGRABBER

HGRABBER __stdcall IC_CreateGrabber();

Here's my attempt at implementing this struct in python, and using it to call that function from the DLL: 这是我尝试在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()

This seems to work, but I'm worried that I'm doing this wrong. 这似乎有效,但我担心我做错了。 I'm not experienced with C, and I don't think I understand the typedef and #define statements which define the HGRABBER type. 我对C没有经验,我认为我不理解定义HGRABBER类型的typedef#define语句。 Am I calling IC_CreateGrabber correctly? 我正确地呼叫IC_CreateGrabber吗? Should I have defined GrabberHandle to be a pointer to a struct, instead of a struct? 我是否应该将GrabberHandle定义为结构的指针,而不是结构?

Thanks for reading, please let me know if I can clarify my question somehow. 感谢您的阅读,如果我能以某种方式澄清我的问题,请告诉我。

You're right that you actually want a POINTER to the Structure , not the Structure itself. 你是对的,你真的想要一个StructurePOINTER ,而不是Structure本身。

Translating the C into English, being very loose (in a way that would be dangerous if you were trying to learn C but is good enough for using ctypes ): 将C翻译成英文,非常宽松(如果你试图学习C但是使用ctypes就足够了,这会很危险):

  • The struct defines a type named struct HGRABBER_t__ , as a structure with one int in it. struct定义了一个名为struct HGRABBER_t__的类型,作为一个结构中包含一个int的结构。
  • The typedef defines a type named HGRABBER_t , as a synonym for struct HGRABBER_t__ . typedef定义名为HGRABBER_t的类型,作为struct HGRABBER_t__的同义词。
  • The #define defines a type named HGRABBER as a pointer to HGRABBER_t . #define将名为HGRABBER的类型定义为指向HGRABBER_t的指针。

So, your GrabberHandle is the equivalent of HGRABBER_t ; 所以,你的GrabberHandle相当于HGRABBER_t ; the equivalent of HGRABBER is: 相当于HGRABBER是:

GrabberHandlePtr = C.POINTER(GrabberHandle)

So you want this: 所以你想要这个:

dll.create_grabber.restype = GrabberHandlePtr

It may be hard to debug the difference. 调试差异可能很难。 AC struct with nothing but an int in it looks identical to an int in memory. 只有一个int AC结构看起来与内存中的int相同。 And on Win32, an int and a pointer are both 32-bit values. 在Win32上, int和指针都是32位值。 And an int named unused is likely to be filled with meaningless garbage, making it hard to distinguish it from a pointer you've accidentally treated as an int. 而一个名为unused的int可能会被无意义的垃圾填充,这使得很难将它与你不小心被视为int的指针区分开来。 So everything will look fine, until you segfault 30 lines later in your code and have no idea what's wrong. 所以一切都会好起来,直到你的代码后面有30行,并且不知道出了什么问题。 :) :)

This library does what you are trying to do: https://github.com/morefigs/py-ic-imaging-control :) 这个库做你想做的事: https//github.com/morefigs/py-ic-imaging-control :)

But to answer your question, the library uses the code: 但要回答你的问题,图书馆使用的代码:

from ctypes import *
import os

class GrabberHandle(Structure):
    pass
GrabberHandle._fields_ = [('unused', c_int)]

# set and check path
dll_path = os.path.join(os.path.expanduser('~'),
                        'Documents\\The Imaging Source Europe GmbH\\TIS Grabber DLL\\bin\\win32\\tisgrabber.dll')
with open(dll_path) as thefile:
    pass

# open DLL
_ic_grabber_dll = windll.LoadLibrary(dll_path)

# create grabber
create_grabber = _ic_grabber_dll.IC_CreateGrabber
create_grabber.restype = POINTER(GrabberHandle)
create_grabber.argtypes = None

# get handle
handle = create_grabber()

Edit: changed code to use a pointer to GrabberHandle as per abarnert's answer as this is correct. 编辑:根据abarnert的回答更改代码以使用指向GrabberHandle的指针,因为这是正确的。 However, in this particular case I have found no practical difference (with the 32-bit DLL), probably because the GrabberHandle structure is so simple. 但是,在这种特殊情况下,我发现没有实际的区别(使用32位DLL),可能是因为GrabberHandle结构非常简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM