P_get
对于“P”指针类型使用PyLong_FromVoidPtr
. 如果地址适合平台long
,则返回 Python int
;否则它返回一个 Python long
,它具有可变精度。这很好,但是当将此整数值作为参数传递时,默认行为是转换为 Cint
,它在所有支持的平台上都是 32 位的。
我认为最好的解决方案是设置argtypes
正确地将参数转换为指针类型。另一种选择是设置restype
为c_void_p
. 使用子类会禁用到 Python 整数的转换。GetResult
通过调用来检查这一点_ctypes_simple_instance
,它实际上返回了它的名称和源注释所暗示的相反内容。(在 2.5 中,这个函数被命名为IsSimpleSubType
,当时的源注释也是错误的。有问题的“简单”从来不是元类PyCSimpleType
,而是基类型_SimpleCData
。)
POSIX:
# Configure the interpreter to load visible extension-
# module symbols, such as _ctypes_simple_instance,
# into the global symbol table.
import sys, DLFCN
sys.setdlopenflags((sys.getdlopenflags() & ~DLFCN.RTLD_LOCAL) |
DLFCN.RTLD_GLOBAL)
from ctypes import *
_ctypes_simple_instance = PyDLL(None)._ctypes_simple_instance
_ctypes_simple_instance.argtypes = py_object,
malloc = CDLL(None).malloc
class my_void_p(c_void_p):
pass
>>> _ctypes_simple_instance(c_void_p)
0
>>> _ctypes_simple_instance(my_void_p)
1
>>> malloc.restype = c_void_p
>>> type(malloc(100))
<type 'int'>
>>> malloc.restype = my_void_p
>>> type(malloc(100))
<class '__main__.my_void_p'>
视窗:
_ctypes_simple_instance
不是由 _ctypes.pyd 导出的。
from ctypes import *
malloc = cdll.msvcrt.malloc
class my_void_p(c_void_p):
pass
>>> malloc.restype = c_void_p
>>> type(malloc(100))
<class 'int'>
>>> malloc.restype = my_void_p
>>> type(malloc(100))
<class '__main__.my_void_p'>