如何从Python ctypes解引用内存位置?
我想把下面的C语言代码用Python的ctypes模块实现:
main() {
long *ptr = (long *)0x7fff96000000;
printf("%lx",*ptr);
}
我知道怎么把这个内存地址当作函数指针来调用,但就是不能正常读取这个内存地址:
from ctypes import *
"""
>>> fptr = CFUNCTYPE(None, None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/ctypes/__init__.py", line 104, in CFUNCTYPE
class CFunctionType(_CFuncPtr):
TypeError: Error when calling the metaclass bases
item 1 in _argtypes_ has no from_param method
"""
fptr = CFUNCTYPE(None, c_void_p) #add c_void_p since you have to have an arg
fptr2 = fptr(0x7fff96000000)
fptr2(c_void_p(0))
#python: segfault at 7fff96000000 ip 00007fff96000000
因为在这里,指令指针指向这个内存地址时会出现段错误,但它确实成功调用了这个地址。不过我就是无法直接读取这个内存地址:
ptr = POINTER(c_long)
ptr2 = ptr(c_long(0x7fff96000000))
#>>> ptr2[0]
#140735709970432
#>>> hex(ptr2[0])
#'0x7fff96000000'
#>>> ptr2.contents
#c_long(140735709970432)
1 个回答
33
ctypes.cast
是一个在 Python 中用来转换数据类型的工具。简单来说,它可以把一种数据类型转换成另一种类型,这样你就可以在程序中更方便地使用这些数据。
想象一下,如果你有一个装着数字的盒子,但你需要把这些数字当作字母来处理。使用 ctypes.cast
就像是给这个盒子换了一个标签,让它变成你需要的类型。这样,你就可以用新的方式来操作这些数据了。
>>> import ctypes
>>> c_long_p = ctypes.POINTER(ctypes.c_long)
>>> some_long = ctypes.c_long(42)
>>> ctypes.addressof(some_long)
4300833936
>>> ctypes.cast(4300833936, c_long_p)
<__main__.LP_c_long object at 0x1005983b0>
>>> ctypes.cast(4300833936, c_long_p).contents
c_long(42)