簡體   English   中英

我是否正確使用ctypes來pythonify這個結構?

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

我正在嘗試使用python的ctypes與這個DLL對話。 許多函數采用或返回HGRABBER類型:

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

(可在此處查看完整的頭文件)。 這是一個返回HGRABBER類型的函數原型的HGRABBER

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_t ; 相當於HGRABBER是:

GrabberHandlePtr = C.POINTER(GrabberHandle)

所以你想要這個:

dll.create_grabber.restype = GrabberHandlePtr

調試差異可能很難。 只有一個int AC結構看起來與內存中的int相同。 在Win32上, int和指針都是32位值。 而一個名為unused的int可能會被無意義的垃圾填充,這使得很難將它與你不小心被視為int的指針區分開來。 所以一切都會好起來,直到你的代碼后面有30行,並且不知道出了什么問題。 :)

這個庫做你想做的事: https//github.com/morefigs/py-ic-imaging-control :)

但要回答你的問題,圖書館使用的代碼:

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()

編輯:根據abarnert的回答更改代碼以使用指向GrabberHandle的指針,因為這是正確的。 但是,在這種特殊情況下,我發現沒有實際的區別(使用32位DLL),可能是因為GrabberHandle結構非常簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM