使用 `ctypes.string_at` 检查 `memoryview` 对象的内存

Use `ctypes.string_at` to check the memory of a `memoryview` object

在 Python 中,memoryview 获取 bytesbytearrays 或任何支持缓冲区协议的内部存储器的查看器。如果我使用 ctypes.string_at 获取 memoryview 对象显示的内存地址处的值,我无法获得有关原始对象的任何信息,如下所示(交互式控制台):

>>> from ctypes import string_at
>>> from sys import getsizeof
>>> a = b'abc'
>>> b = memoryview(a)
>>> b
<memory at 0x7fb8e99c8408>
>>> string_at(0x7fb8e99c8408, getsizeof(a))
b'\x02\x00\x00\x00\x00\x00\x00\x00@\x0e\x8a\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00H\x10\x96\xe9\xb8\x7f\x00\x00\xff\xff\xff\xff'

结果显示没有 b'abc' 的证据。那么memoryview对象的对象字符串中的内存0x7fb8e99c8408到底是什么意思呢?我们可以直接验证内存来证明memoryview肯定反映了内存吗?

这是 memoryview 对象在内存中的地址,而不是字符串对象本身(假设 CPython 实现)。为了查看字符串字节,您需要 id(s)id(memv.obj):

>>> import sys
>>> import ctypes
>>> s = b"abc"
>>> memv = memoryview(s)
>>> s_mem = ctypes.string_at(id(s), sys.getsizeof(s))
>>> s_mem
b'\x02\x00\x00\x00\x00\x00\x00\x00`\xa2\x90\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00CBT+\xa6\xce&\xa5abc\x00'
>>> s_mem[-len(s)-1:]
b'abc\x00'

如果您对输出感到好奇,可以在 Python here.

中阅读有关字符串对象表示的更多信息