2015-09-02 7 views
3

Я не могу понять, как получить виртуальный адрес стандарта mmap объектов в Python (из модуля mmap). Документированные методы, по-видимому, имеют доступ к памяти как к массиву байтов или как к символьным строкам.Как получить адрес mmap-ed памяти в Python?

Но мне нужно получить доступ к памяти mmap'ом точно через 2 или 4 байта за раз - потому что эта память в моем приложении сопоставляется с аппаратными регистрами (think/dev/mem или GPIO или таковыми). Доступ к памяти таким образом возможен с ctypes module - но для этого мне нужен указатель - или виртуальный адрес - отображения.

В настоящее время я преодолеваю это с помощью собственных функций open() и mmap() из libc (благодаря тем же типам), но скорее не будет.

Почему модуль mmap не обеспечивает простой способ получить адрес памяти? Надеемся, что я что-то очевидное отсутствую ...

- дд

ответ

2

mmap объекты поддерживают записываемый интерфейс буфера, так что вы можете использовать метод from_buffer класса, ctypes классов с mmap объекта в качестве аргумента, чтобы получить a ctypes объект, который разделяет память файла mmap.

buf = mmap.mmap(fd, mmap.PAGESIZE, mmap.MAP_SHARED, mmap.PROT_WRITE) 
int_pointer = ctypes.c_int.from_buffer(buf) 
+0

Отлично! Большое спасибо. – ddbug

+0

Вчера я сделал быстрый тест и хотел уже отметить ваш ответ. но тогда я не могу сделать «реальную» работу кода с Python 2.7 на Linux. Точный код, который вы отправили, не разрешен. Я не понимаю, почему. Когда я изменяю MAP_SHARED на MAP_PRIVATE, mmap преуспевает. Когда я изменяю PROT_WRITE на PROT_READ, mmap преуспевает. Но мне нужно, чтобы он был общим (видимым в глобальном масштабе) и доступным для записи. Не могли бы вы дать еще один намек, пожалуйста? – ddbug

0

Вот более полный код, что мне нужно получить работу, с Python 2.7 на Linux:

import os, io 
from mmap import * 
from ctypes import * 

winsize= 0 
devmemfd= -1 
curr_va=0 
curr_base=0 
devf = None 
mm = None 
ptr4 = None 

def mm_init(path = 'test.dat') : 
    global curr_va,winsize,devmemfd,mm,devf,ptr4 
    devf = open(path, "rwb") 
    devmemfd = devf.fileno() 
    mm = mmap(devmemfd, PAGESIZE, MAP_SHARED, PROT_WRITE) # this FAILS if MAP_SHARED 
    ptr4 = POINTER(c_uint32)(c_uint32.from_buffer(mm)) # this FAILS is I make mapping readonly 
    curr_va = cast(ptr4, c_void_p).value 
    winsize=PAGESIZE 
    print("OK") 

Опять же, я должен что-то отсутствует очевидный, как я новичок в Python

- дд

Traceback:

>>> mm_init() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "mm-test.py", line 17, in mm_init 
    mm = mmap(devmemfd, PAGESIZE, MAP_SHARED, PROT_WRITE) 
mmap.error: [Errno 13] Permission denied 
+0

Как это происходит? Исключения? Опубликовать трассировку. –

+0

Traceback, добавленный выше. Кстати, я запускаю это как root. так что значит «разрешение отказано» точно? Это работает для вас без ошибок? - dd – ddbug

+0

Хорошо, нашел ошибку. Режим open() должен быть «r +», а не «rw». Точно так же, как в C. Python3 обнаруживает это и дает сообщение об ошибке, 2.7 тихо делает что-то странное. Еще раз спасибо. - dd – ddbug