如何使用 c_void_p 作为句柄
How to use c_void_p as a handle
我有一个 .dll,我正在尝试使用 ctypes 访问。 .dll 的 header 如下所示:
typedef void* CMS_HANDLE;
CMS_HANDLE WINAPI cmsOpen( int nDeviceID , int nComType);
BOOL WINAPI cmsClose(CMS_HANDLE hCms);
我的 python 代码如下所示:
from ctypes import WinDLL, c_void_p, c_double, byref
dll = WinDLL("CMS_APIX64.dll")
handle = c_void_p(dll.cmsOpen(15, 3))
print(handle)
dll.cmsClose(handle)
它正确地 dll.cmsOpen 和 returns 一个值。但是,它不喜欢我传递给 dll.cmsClose():
的值
c_void_p(18446744072525716064)
Traceback (most recent call last):
File "C:\Users\mjwilson\dev\Cms100-tool\cms100-tool.py", line 40, in <module>
dll.cmsClose(handle)
OSError: exception: access violation reading 0xFFFFFFFFB9701A60
我确定我只是在用手柄做一些愚蠢的事情。有任何想法吗?
(我有 C-code 适用于此 .dll)
问题出在 64 位 Python,句柄是 64 位,但 ctypes 假设 return 类型是 c_int
(32 位),如果没有具体定义的话,所以当您将 cmsOpen
return 值放入 c_void_p
.
时,该值已被截断
什么是 always 好的做法,是为您使用的每个函数完全定义 .argtypes
和 .restype
。这将正确转换参数,并在传递不正确或错误数量的参数时提供错误检查:
from ctypes import *
dll = WinDLL("CMS_APIX64.dll")
dll.cmsOpen.argtypes = c_int,c_int
dll.cmsOpen.restype = c_void_p
dll.cmsClose.argtypes = c_void_p,
dll.cmsClose.restype = c_int
handle = dll.cmsOpen(15, 3)
print(handle)
dll.cmsClose(handle)
我有一个 .dll,我正在尝试使用 ctypes 访问。 .dll 的 header 如下所示:
typedef void* CMS_HANDLE;
CMS_HANDLE WINAPI cmsOpen( int nDeviceID , int nComType);
BOOL WINAPI cmsClose(CMS_HANDLE hCms);
我的 python 代码如下所示:
from ctypes import WinDLL, c_void_p, c_double, byref
dll = WinDLL("CMS_APIX64.dll")
handle = c_void_p(dll.cmsOpen(15, 3))
print(handle)
dll.cmsClose(handle)
它正确地 dll.cmsOpen 和 returns 一个值。但是,它不喜欢我传递给 dll.cmsClose():
的值c_void_p(18446744072525716064)
Traceback (most recent call last):
File "C:\Users\mjwilson\dev\Cms100-tool\cms100-tool.py", line 40, in <module>
dll.cmsClose(handle)
OSError: exception: access violation reading 0xFFFFFFFFB9701A60
我确定我只是在用手柄做一些愚蠢的事情。有任何想法吗? (我有 C-code 适用于此 .dll)
问题出在 64 位 Python,句柄是 64 位,但 ctypes 假设 return 类型是 c_int
(32 位),如果没有具体定义的话,所以当您将 cmsOpen
return 值放入 c_void_p
.
什么是 always 好的做法,是为您使用的每个函数完全定义 .argtypes
和 .restype
。这将正确转换参数,并在传递不正确或错误数量的参数时提供错误检查:
from ctypes import *
dll = WinDLL("CMS_APIX64.dll")
dll.cmsOpen.argtypes = c_int,c_int
dll.cmsOpen.restype = c_void_p
dll.cmsClose.argtypes = c_void_p,
dll.cmsClose.restype = c_int
handle = dll.cmsOpen(15, 3)
print(handle)
dll.cmsClose(handle)