Python类型中的ULONG_PTR

Python类型中的ULONG_PTR,python,windows,winapi,ctypes,Python,Windows,Winapi,Ctypes,我在Windows上使用Python ctypes库并实现了一个结构。它有两个ULONG_PTR类型的成员,在ctypes.wintypes中不可用。根据ULONG_,PTR是一个取决于指针大小的ULONG。我可以在Python中使用wintypes.ULONG而不是ULONG_PTR吗?或者有更好的方法吗 我发现了几种不同的重叠结构实现:使用指针(ULONG))代替ULONG_PTR和-LPVOID。但ULONG_PTR不是指针,因此这些类型不适合使用。我错了吗?我试过LPVOID,它可以工作

我在Windows上使用Python ctypes库并实现了一个结构。它有两个ULONG_PTR类型的成员,在ctypes.wintypes中不可用。根据ULONG_,PTR是一个取决于指针大小的ULONG。我可以在Python中使用wintypes.ULONG而不是ULONG_PTR吗?或者有更好的方法吗


我发现了几种不同的重叠结构实现:使用指针(ULONG))代替ULONG_PTR和-LPVOID。但ULONG_PTR不是指针,因此这些类型不适合使用。我错了吗?我试过LPVOID,它可以工作,但我不是一个C族,所以我想知道我的情况有什么不同吗?

使用
C\u void\p
LPVOID
。这将是指针的大小,实际类型无关紧要,因为您永远不会访问
Internal
InternalHigh
成员

使用
指针(ULONG)
可以工作,但
指针(c_char)
或任何其他指针类型也可以工作。类型仍然是错误的,除非现在您正在分配一个实际上不需要的新类型对象

如果需要使用内部成员的“正确”类型访问它们,那么需要根据使用的是32位还是64位版本的Python定义两种不同重叠结构中的一种。比如:

if ctypes.sizeof(ctypes.c_void_p) == 8:
    ULONG_PTR = ctypes.u_longlong
else:
    ULONG_PTR = ctypes.u_long

class OVERLAPPED(ctypes.Structure): 
    _fields_ = [("Internal", ULONG_PTR),
                ("InternalHigh", ULONG_PTR),
                ...]

使用
c\u void\u p
LPVOID
。这将是指针的大小,实际类型无关紧要,因为您永远不会访问
Internal
InternalHigh
成员

使用
指针(ULONG)
可以工作,但
指针(c_char)
或任何其他指针类型也可以工作。类型仍然是错误的,除非现在您正在分配一个实际上不需要的新类型对象

如果需要使用内部成员的“正确”类型访问它们,那么需要根据使用的是32位还是64位版本的Python定义两种不同重叠结构中的一种。比如:

if ctypes.sizeof(ctypes.c_void_p) == 8:
    ULONG_PTR = ctypes.u_longlong
else:
    ULONG_PTR = ctypes.u_long

class OVERLAPPED(ctypes.Structure): 
    _fields_ = [("Internal", ULONG_PTR),
                ("InternalHigh", ULONG_PTR),
                ...]

指针(ULONG)
错误,显然是因为误解了
\u PTR
后缀。没有必要猜测;就在MSDN上。这就是我看到这些例子时想到的_PTR不是指针。我选择ULONG是因为我在wintypes中错过了WPARAM。现在我意识到我也犯了一个错误,因为我使用的是64位系统,应该使用c_ulonglong。也许你可以把你对WPARAM的评论转换成一个答案?目前的答案很好。我只是想澄清一下,在需要0值而不是
None
的情况下,使用
c\u void\u p
是错误的,例如
InternalHigh
。此外,使用
WPARAM
可以节省几行代码,但最终结果与答案中有条件地分配
c_ulonglong
vs
c_ulong
指针(ulong)的代码相同,显然是错误的,原因是对
\u PTR
后缀的误解。没有必要猜测;就在MSDN上。这就是我看到这些例子时想到的_PTR不是指针。我选择ULONG是因为我在wintypes中错过了WPARAM。现在我意识到我也犯了一个错误,因为我使用的是64位系统,应该使用c_ulonglong。也许你可以把你对WPARAM的评论转换成一个答案?目前的答案很好。我只是想澄清一下,在需要0值而不是
None
的情况下,使用
c\u void\u p
是错误的,例如
InternalHigh
。此外,使用
WPARAM
可以节省几行,但最终结果与答案中有条件地指定
c_ulonglong
vs
c_ulong
的代码相同。如果需要类型的
getfunc
返回0而不是
None
,则使用
c_void\u p
是不正确的。为对象
、函数结果以及访问结构字段和数组/指针索引调用
getfunc
。整数定义通常更为正确。您可以使用别名
ULONG\u PTR=ctypes.wintypes.WPARAM
,它是根据指针大小有条件地定义的。@Ross Ridge,谢谢您的回答。您能否详细说明我的场景中不正确的类型如何影响执行或正确性?我看到,从技术上讲,它们都会工作,但它们如何改变程序行为?@wombatonfire它不会影响程序行为,除非您以某种方式访问内部成员。因为它们仅供内部使用,所以您不应该设置或阅读它们。如果您不访问内部成员,则任何为这些成员保留足够空间的类型(例如,对于32位大小写,
c_char*4
)都可以工作。这就是为什么您会看到实现中的变化,任何正确大小的东西在实践中都会起作用。如果您需要类型的
getfunc
返回0而不是
None
,则使用
c\u void\p
是不正确的。为对象
、函数结果以及访问结构字段和数组/指针索引调用
getfunc
。整数定义通常更为正确。您可以使用别名
ULONG\u PTR=ctypes.wintypes.WPARAM
,它是根据指针大小有条件地定义的。@Ross Ridge,谢谢您的回答。您能否详细说明我的场景中不正确的类型如何影响执行或正确性?我看到,从技术上讲,它们都会工作,但它们如何改变程序行为?@wombatonfire它不会影响程序行为,除非您以某种方式访问内部成员。因为它们仅供内部使用,所以您不应该设置或阅读它们。如果您不访问内部成员,则任何为这些成员保留足够空间的类型(例如,对于32位大小写,
c_char*4
)都可以工作。这就是为什么您会在实现中看到变化,任何正确大小的东西都会在实践中起作用。