从Python调用一个接收句柄指针的DLL函数(Win32)

3 投票
1 回答
1867 浏览
提问于 2025-04-18 04:12

我正在尝试为一台运行Windows XP的机器写一个非常简单的相机控制器。我本来打算用C语言来写,但我想直接用ctypes来访问dll文件,这样可能更简单。

要启动相机,你需要调用:

BeginHVDevice(int nDevice, HHV *pHandle)

*pHandle是一个指向相机句柄的指针,在.h文件中,它被简单地定义为

typedef HANDLE HHV;

我原以为下面的代码应该可以工作:

from ctypes import *
from ctypes.wintypes import *


ailt_lib = cdll.LoadLibrary("HVDAILT")
load_camera = ailt_lib.BeginHVDevice
load_camera.restype = c_int
load_camera.argtypes = [c_int, POINTER(HANDLE)]

def initDev(res=(800,600)):

    cam_int = c_int(1)
    cam_handle_type = POINTER(HANDLE)
    print cam_handle_type
    cam_handle = cam_handle_type()
    print cam_handle

    cam_stat = load_camera(cam_int, cam_handle )
    print cam_stat
    return cam_handle

但是,当我调用initDev()时,出现了一个错误,提示ValueError: Procedure called with not enough arguments (8 bytes missing) or wrong calling convention。这让我觉得可能是我传递的指针不兼容,但我搞不清楚这个函数实际上需要什么样的参数。

我花了几天时间在StackOverflow上搜索,查看ctypes的文档,尝试各种组合,但还是没有找到答案。

1 个回答

1

看起来这个函数使用的是 stdcall 调用约定,而不是 cdecl。也就是说,你应该用 ctypes.WinDLL 来代替 ctypes.CDLL。另外,它需要一个指向内存位置的指针,以便可以存储句柄,但你传递了一个 NULL 指针。你应该传递一个指向 wintypes.HANDLE 的引用。

from ctypes import *
from ctypes.wintypes import *

ailt_lib = WinDLL("HVDAILT")
load_camera = ailt_lib.BeginHVDevice
load_camera.restype = c_int
load_camera.argtypes = [c_int, POINTER(HANDLE)]

def initDev(res=(800,600)):    
    cam_int = 1
    cam_handle = HANDLE()    
    cam_stat = load_camera(cam_int, byref(cam_handle))
    print 'cam_stat:', cam_stat
    print 'cam_handle:', cam_handle
    return cam_handle

撰写回答