获取只读mmap对象的地址

时间:2015-11-28 22:52:47

标签: python python-3.x mmap

我目前正致力于使用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,但如果还有另一种方法,我宁愿不这样做,所以任何建议或解决方法都会受到赞赏。

2 个答案:

答案 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函数现在可以使用所需的任何指针算法自由地从缓冲区读取,但是当然不能对其进行写操作。