Как отправить вектор & lt; vector & lt; type & gt; & gt; через MapViewOfFile

У меня есть следующий код в родительском процессе:

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;
};

Как правильно получить мой вектор у ребенка?

0

Решение

Это не сработает так, как вы делаете это в данный момент. Отображенная память будет содержать n & m и внутренняя структура векторного класса, который, вероятно, будет парой указателей, в зависимости от вашей реализации STL. Вслед за грузом мусора. Вы не сможете безопасно получить доступ к этим указателям из другого процесса, так как он находится в другом адресном пространстве.

Вам необходимо скопировать память, на которую указывает вектор, в отображенную память и восстановить вектор на другой стороне.

Кроме того, размер памяти, который вам нужен, не будет sizeof (int) * n * m. Похоже, вы хотите иметь 2 целых & м в структуре и коллекции п * м удваивается.

Итак, выделите 2 * sizeof (int) + n * m * sizeof (double). Скопируйте n & м в память, а затем скопировать строки матрицы в.
На принимающей стороне прочитайте n & м, а затем десериализовать данные в ваш вектор векторов.

Может быть, сделать структуру так:

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));
}

Все не проверено и может быть сделано более оптимальным, но, надеюсь, это лучше объясняет, что вам нужно делать.

1

Другие решения

Вам необходимо переопределить объект-распределитель по умолчанию для вектора, чтобы он работал полностью в пространстве памяти MapView, поскольку объект-распределитель по умолчанию будет использовать память кучи для всех распределений. Есть очень старая статья Dr.Dobbs, написанная Бьярном Страуструпом (создателем C ++), в которой рассказывается, как именно выполнить эту задачу:

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

1

Это не сработает, вектор будет содержать только указатель, фактические данные размещаются в куче. Ваш memcpy только копирует указатель, который недопустим на стороне получателя.

0
По вопросам рекламы [email protected]