使用 ctypes 从 python 访问 boost::进程间共享内存块

2024-04-18

我在 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];
};

As:

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 可以实现这一点,但有一个替代方案窗口共享内存 http://www.boost.org/doc/libs/1_58_0/doc/html/boost/interprocess/windows_shared_memory.html而不是默认的共享内存对象 http://www.boost.org/doc/libs/1_58_0/doc/html/boost/interprocess/shared_memory_object.html.

工作代码如下:

  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 存储库完整的示例解决方案 https://github.com/teeks99/py_boost_shmem.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ctypes 从 python 访问 boost::进程间共享内存块 的相关文章

随机推荐