gpt4 book ai didi

python - ctypes 将 c_uint64 转换为 c_char_p

转载 作者:太空宇宙 更新时间:2023-11-04 01:39:23 25 4
gpt4 key购买 nike

from ctypes import *

In [27]: sizeof(c_char_p)
Out[27]: 8

In [28]: sizeof(c_uint64)
Out[28]: 8

In [29]: cast(c_uint64(0), c_char_p)
---------------------------------------------------------------------------
ArgumentError Traceback (most recent call last)

/Users/az/Programmierung/PyCPython/<ipython console> in <module>()

/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ctypes/__init__.pyc in cast(obj, typ)
479 _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
480 def cast(obj, typ):
--> 481 return _cast(obj, obj, typ)
482
483 _string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)

ArgumentError: argument 1: <type 'exceptions.TypeError'>: wrong type

为什么 cast 会失败?

如果 sizeof 两种类型相同,是否可以替代 ctypes.cast

最佳答案

c_uint64 是内存地址吗?如果是这样,那么您可以这样做:

>>> n = c_uint64(1234567890) #assume this is a valid memory address...beware of segfaults
>>> p = c_char_p(n.value)
>>> #or..
>>> p.value = n.value #special semantics for c_char_p - accepts both addresses and strings

(参见 http://docs.python.org/library/ctypes.html#ctypes.c_char_p )

或者,如果您想做的是将存储在 c_uint64 中的值重新解释为一个 8 字节空终止字符缓冲区,那么您需要将指向 c_uint64 的指针转换为 c_char_p...

>>> n = c_uint64(ord("A"))
>>> n
c_ulong(65L)
>>> p = cast(pointer(n), c_char_p)
>>> p
c_char_p(47101614291216)
>>> p.value
'A'

看起来如果 ctypes 不是空终止的,它会保护你免受缓冲区溢出:

>>> n2 = c_uint64(0xFFFFFFFFFFFFFFFF)
>>> p2 = cast(pointer(n2), c_char_p)
>>> p2.value[0]
'\xff'
>>> p2.value
'\xff\xff\xff\xff\xff\xff\xff\xff'
>>> p2.value[9]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range

更新以回应 Albert 的评论:

I want to know why cast doesn't work here

原因的答案在文档和代码中 - http://docs.python.org/library/ctypes.html#ctypes.cast

ctypes.cast(obj, type) This function is similar to the cast operator in C. It returns a new instance of type which points to the same memory block as obj. type must be a pointer type, and obj must be an object that can be interpreted as a pointer.

契约(Contract)在 code 中是这样执行的:

_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
def cast(obj, typ):
return _cast(obj, obj, typ)

因此,转换(对象)的第一个参数必须可转换为 c_void_p。在 source 中,查看 c_void_p_from_param()。这是转换为 c_void_p 的地方。有用于 Python 整数、Python 字符串、Python unicode 字符串、c_void_p、ctypes 数组/指针、byref 结果、函数指针、c_char_p/c_wchar_p 以及定义了 _as_parameter_() 方法的任何对象的转换器。

没有用于 ctypes 整数对象的转换器。我只查看 2.6 代码(因为这就是您正在使用的代码),因此在 2.7 或 3.x 中情况可能并非如此。

至于理由 - 这个问题必须提交给开发人员。

...if there is a generic version which always works (for all cases, not just c_char_p).

据我所知,解决方案与我在第一个示例中展示的一样。使用 Python 整数构造指针或分配给指针对象的值成员(转换器知道如何从 Python 整数转换)。 cast() 将不起作用,因为它是如何实现的。

关于python - ctypes 将 c_uint64 转换为 c_char_p,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6685801/

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