【问题标题】:How to send vector<vector<type>> via MapViewOfFile如何通过 MapViewOfFile 发送向量<vector<type>>
【发布时间】:2012-12-08 00:07:19
【问题描述】:

我在父进程中有以下代码:

vector<vector<double> > matrix(n); /* matrix NxM */
/* pushing data */
HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
    0, PAGE_READWRITE, 0, 2*sizeof(int) + sizeof(double)*n*m, lpName);

LPVOID lp = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);

mat_tmp* tmp = (mat_tmp*)lp;
tmp->n = n; tmp->m = m;
tmp->vv = vector<vector<double> >(matrix.begin(), matrix.end());

在一个子进程中我试图接收这个向量>,但我的子进程每次都会终止。

LPTSTR lpName = _tcsdup(TEXT(map_name));
HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
    0, PAGE_READWRITE, 0, 2*sizeof(int) + sizeof(double)*n*m, lpName);
LPVOID lp = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);

mat_tmp * tmp = (mat_tmp*)lp;
vector<vector<double> > matrix(tmp->vv.begin(), tmp->vv.end());

当我尝试在子进程中使用来自matrix 的数据时发生错误。 小结构如下:

struct mat_tmp
{
    int n; int m; vector<vector<double> > vv;
};

我怎样才能在孩子身上正确接收我的载体?

【问题讨论】:

    标签: c++ winapi file-mapping filemap


    【解决方案1】:

    您需要覆盖向量的默认分配器对象,使其完全在 MapView 的内存空间中工作,因为默认分配器对象将使用堆内存进行所有分配。 Bjarne Stroustrup(C++ 的创建者)写了一篇非常古老的 Dr.Dobbs 文章,其中详细说明了如何完成这项任务:

    http://www.drdobbs.com/creating-stl-containers-in-shared-memory/184401639

    【讨论】:

      【解决方案2】:

      它不会像你现在那样工作。映射的内存将包含 n 和 m 以及向量类的内部结构,这可能是几个指针,具体取决于您的 STL 实现。紧随其后的是一堆垃圾。您将无法从其他进程安全地访问这些指针,因为它位于不同的地址空间中。

      你需要将向量指向的内存实际复制到映射的内存中,并在另一边重构向量。

      此外,您需要的内存大小不会是 sizeof(int)*n*m。看起来你想在结构中有 2 个整数 n & m 和一个 n*m 双精度数的集合。

      所以,分配 2*sizeof(int) + n*m*sizeof(double)。将 n & m 复制到内存中,然后将矩阵的行复制进去。 在接收端,读取 n 和 m,然后将数据反序列化为向量向量。

      也许把结构做成这样:

      struct mat_tmp
      {
          int n; int m; double vv[1];
      };
      

      然后,直接复制到共享内存中:

      double* dst = tmp.vv;
      for (size_t y = 0; y < matrix.size(); ++y) {
         memcpy(dst, &(matrix[y][0]), matrix[y].size()*sizeof(double));
         dst += matrix[y].size();
      }
      

      另一边,

      dst_matrix.resize(n);
      for (size_t y = 0; y < n; ++y) {
          dst_matrix[y].resize(m);
          memcpy(&(dst_matrix[y][0]), tmp + (y * m), m * sizeof(double));
      }
      

      所有内容都未经测试,可以做得更优化,但希望它能更好地解释您需要做什么。

      【讨论】:

      • 我不明白如何将矩阵的行复制到内存中。我将 n&m 复制到内存中,然后将我的矩阵从 begin() 复制到 end() 到 struct 的向量中,但它不适用于孩子。
      • 如你所见,我试图通过迭代器复制向量,它不起作用
      • 你没有抓住重点 - 你不能在共享内存中拥有向量。
      • 更新了答案,给出了一个复制的例子。
      • 我已经有了double vv[1],但是我的老师说这和我所有的代码一样糟糕。谢谢你,我会给他这个链接!
      【解决方案3】:

      这行不通,向量只会保存一个指针,实际数据是堆分配的。你的 memcpy 只复制指针,在收件人这边是无效的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-05
        • 1970-01-01
        • 1970-01-01
        • 2018-09-20
        • 2011-02-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多