将mmap指针从C传递到Python作为mmap对象

0 投票
1 回答
1075 浏览
提问于 2025-04-17 15:10

我正在尝试将一个C语言库(beaglebone PRU驱动程序prussdrv.c)与Python连接起来。我想要访问的特定函数返回一个内存映射指针,下面是示例代码:

int __prussdrv_memmap_init(void) {
      prussdrv.pru0_dataram_base = mmap(0, prussdrv.pruss_map_size, PROT_READ | PROT_WRITE,
         MAP_SHARED, prussdrv.mmap_fd, PRUSS_UIO_MAP_OFFSET_PRUSS);
      ...

int prussdrv_map_prumem(unsigned int pru_ram_id, void **address) {    
     switch (pru_ram_id) {
     case PRUSS0_PRU0_DATARAM:
          *address = prussdrv.pru0_dataram_base;
           break;

prussdrv_map_prumem (DATARAM[PRU_NUM], &pruDataMem);
pruDataMem_byte = (unsigned char*) pruDataMem;

我想把pruDataMem或pruDataMem_byte封装起来,然后作为一个内存映射对象传递给Python。有没有简单的方法可以做到这一点?我看过capsule和ctypes,但它们似乎无法满足我的需求。

1 个回答

0

我觉得没有办法直接从这种本地映射创建一个Python的 mmap 对象。因为相关的协议没有公开,内部格式也不清楚。

不过,当然可以查看 源代码。只要你的映射符合通过 new_mmap_object 创建的所有标准,你可以手动构建一个 mmap_object 来包装这些信息,然后把它传回去。(你实际上不能直接访问 mmap_object 类型,因为它不在任何头文件里。但如果你创建一个等效的类型,或者直接复制粘贴代码,你就可以把它当作 PyObject * 来使用,只要它的类型字段指向正确的类型,就能正常工作。)

不过,我不太确定你是否真的需要这样做。你真的需要一个 mmap 吗?还是说你只需要一个可以当作字符串、列表或迭代器的缓冲区?因为后者要简单得多。为此,你可以创建一个 旧式缓冲区新式缓冲区 类——或者,如果你只需要Python 2.7及以上版本,可以使用具体的 memoryview 类型。从概念上讲,返回映射内存的视图而不是映射本身似乎是合理的,但我能想象在某些情况下这样做可能不太合适。

最后,你总是可以创建一个新的类,提供你想要的任何接口来围绕你的映射,并且可以让它尽可能像(或不像) mmap

撰写回答