gpt4 book ai didi

python - 为什么设置 ctypes dll.function.restype=c_void_p 返回 long?

转载 作者:太空狗 更新时间:2023-10-30 00:56:31 25 4
gpt4 key购买 nike

奇怪的是,即使在设置了 restype 之后,python 仍会返回 long 而不是 c_void_p

例如;

# python code
from ctypes import *
dll = windll.LoadLibrary("my.dll")
dll.my_object_create.restype = c_void_p
x = dll.my_object_create()
print type(x) # prints <type 'long'>

//c++ code
my_object *my_object_create() { return new my_object(); }
void my_object_destroy(my_object *obj) { delete obj; }

我最近不得不修复一个错误,在该错误中,将 x 反馈给另一个 ctypes 函数时,指针被践踏了。这是通过将初始 dll 调用更改为

x = c_void_p(dll.my_object_create())

...我猜 ctypes 将 x 视为 4 个字节长而不是 8 个字节(64 位架构)。

所以我想知道现有行为是否有原因将您引入这个陷阱?

最佳答案

P_get对于'P' pointer type使用 PyLong_FromVoidPtr .如果地址适合平台 long,它返回一个 Python int;否则它返回一个 Python long,它具有可变的精度。很好,但是当将此整数值作为参数传递时,默认行为是 convert to a C int ,在所有支持的平台上都是 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'>

window :

_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'>

关于python - 为什么设置 ctypes dll.function.restype=c_void_p 返回 long?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17840144/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com