获取只读 mmap 对象的地址
Get address of read-only mmap object
我目前正在 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 获取底层内存地址。
我有一种情况希望能够以只读的方式打开这个 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,但如果有另一种方法,我宁愿不这样做,所以任何建议或解决方法都将不胜感激。
使用 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
要获取指向只读内存映射(mmap.mmap
实例)的 char*
指针,然后可以将其传递给 C 函数,关键是 CFFI 的 ffi.from_buffer()
(docs).
因此,如果您已经拥有:
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 函数现在可以自由地从缓冲区中读取,使用您需要的任何指针算法,但当然不能写入它。
我目前正在 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
我有一种情况希望能够以只读的方式打开这个 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,但如果有另一种方法,我宁愿不这样做,所以任何建议或解决方法都将不胜感激。
使用 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
要获取指向只读内存映射(mmap.mmap
实例)的 char*
指针,然后可以将其传递给 C 函数,关键是 CFFI 的 ffi.from_buffer()
(docs).
因此,如果您已经拥有:
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 函数现在可以自由地从缓冲区中读取,使用您需要的任何指针算法,但当然不能写入它。