繁体   English   中英

使用ctypes从python访问boost :: interprocess共享内存块

[英]Access a boost::interprocess shared memory block from python with ctypes

我在Windows上运行的C ++程序中有一个结构,我想使用ctypes通过Python中的共享内存进行访问。 例如:

#define MAX_ENTITIES 30

struct State
{
   double x;
   double y;
   double z;
};

struct Stat
{
   unsigned int numAvailable;
   unsigned int numUsed;
};

struct TransferData
{
   double exLg;
   float other;
   unsigned int more;
   int more2;
   unsigned char next;
   bool statusReady;

   Stat status;
   State entities[MAX_ENTITIES];
};

如:

import ctypes

MAX_ENTITIES = 30


class State(ctypes.Structure):
    _fields_ = [
        ('x', ctypes.c_double),
        ('y', ctypes.c_double),
        ('z', ctypes.c_double)
    ]


class Stat(ctypes.Structure):
    _fields_ = [
        ('numAvailable', ctypes.c_uint),
        ('numUsed', ctypes.c_uint)
    ]


class TransferData(ctypes.Structure):
    _fields_ = [
        ('exLg', ctypes.c_double),
        ('other', ctypes.c_float),
        ('more', ctypes.c_uint),
        ('more2', ctypes.c_int),
        ('next', ctypes.c_ubyte),
        ('statusReady', ctypes.c_bool),
        ('status', Stat),
        ('entities', State * MAX_ENTITIES)
    ]

我希望:

shmem = mmap.mmap(-1, ctypes.sizeof(TransferData.TransferData), 
          "TransferDataSHMEM")
data = TransferData.from_buffer(shmem)

将使数据成为C ++端表示的共享内存镜像,但全为零。

我发现的技巧实际上是在boost :: interprocess方面。 而不是建立普通的共享内存区域:

  shared_memory_object shmem(open_or_create, "CppTransferDataSHMEM", read_write);
  shmem.truncate(sizeof(TransferData));
  mapped_region region(shmem, read_write);
  TransferData* data = reinterpret_cast<TransferData*>(region.get_address());

Windows上的Python(带有-1文件描述符)要求将内存映射到页面文件。 Boost启用了此功能,但是使用了替代方法windows_shared_memory而不是默认的shared_memory_object

工作代码如下:

  windows_shared_memory shmem(create_only, "TransferDataSHMEM", 
     read_write, sizeof(TransferData));
  mapped_region region(shmem, read_write);
  std::memset(region.get_address(), 0, sizeof(TransferData));

  TransferData* data = reinterpret_cast<TransferData*>(region.get_address());

我已经使用完整的示例解决方案创建了一个github存储库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM