我目前正致力于使用some code对象在进程之间共享某些状态的mmap
。用例是一组进程,可以访问共享mmap支持的数组中的一些只读数据。部分内容涉及对底层内存表示进行一些算术运算,我使用类似于this question的ctypes来获取底层内存地址。
我有一种情况,希望能够打开此mmap文件,只读取只读取数据的进程。但是,当我这样做时,我不确定如何获得指针地址。以下是我可以做的最接近这个问题的最小例子:
import mmap
import ctypes
filename = "test"
with open(filename, 'rb+') as fd:
buf = mmap.mmap(fd.fileno(), 0)
int_pointer = ctypes.c_int.from_buffer(buf)
with open(filename, 'rb') as fd:
test_mmap_ro = mmap.mmap(
fd.fileno(), 0, access=mmap.ACCESS_READ,
)
int_pointer2 = ctypes.c_int.from_buffer(test_mmap_ro) #fails here
在Python3上运行时失败了:
TypeError: must be read-write buffer, not mmap.mmap
虽然Python2给出了这个:
TypeError: mmap can't modify a readonly memory map.
鉴于我实际上想要使用只读存储器映射,我该怎么做?如果必须的话,我会改为可写的mmap,但如果还有另一种方法,我宁愿不这样做,所以任何建议或解决方法都会受到赞赏。
答案 0 :(得分:3)
使用ctypes
我最终得到了这个:
obj = ctypes.py_object(buf)
address = ctypes.c_void_p()
length = ctypes.c_ssize_t()
ctypes.pythonapi.PyObject_AsReadBuffer(obj, ctypes.byref(address), ctypes.byref(length))
int_pointer = address.value
答案 1 :(得分:0)
要获取指向您的只读内存映射(char*
实例)的mmap.mmap
指针,然后可以将其传递给C函数,关键是CFFI的ffi.from_buffer()
{{3 }}。
因此,如果您已经拥有:
import mmap
with open("my_huge_file.bin", "rb") as stream:
buf = mmap.mmap(stream.fileno(), 0, access=mmap.ACCESS_READ)
要通过CFFI调用C函数,并将指针传递到映射的内存,请执行以下操作:
from ._my_cffi_module import lib as my_cffi_module, ffi
cbuf = ffi.from_buffer(buf)
my_cffi_module.my_c_function(cbuf, 1, 2, 3) # Whatever your parameters may be
您的C函数现在可以使用所需的任何指针算法自由地从缓冲区读取,但是当然不能对其进行写操作。