Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get address of read-only mmap object

I'm currently working on some code that shares some state between processes using a mmap object. The use case is a bunch of processes that have access to some read-only data in a shared mmap backed array. Part of this involves doing some arithmetic on the underlying memory representation, I'm using ctypes much like in this question to get a the underlying memory address.

I have a situation where want to be able to open this mmap file as read only by the processes that only read data. However when I do that I'm not sure how to get the pointer address in that case. The following is as close to a minimal example of this problem as I can make:

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

Running on Python3 this fails with this:

TypeError: must be read-write buffer, not mmap.mmap

While Python2 gives this:

TypeError: mmap can't modify a readonly memory map.

Given that I actually want to use a read only memory map how can I do this? I'll change to a writeable mmap if I have to, but I would rather not if there's another way to do this, so any suggestions or workarounds would be appreciated.

like image 229
shuttle87 Avatar asked Nov 28 '15 22:11

shuttle87


1 Answers

Using ctypes I ended up with this:

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
like image 180
shuttle87 Avatar answered Sep 28 '22 01:09

shuttle87