Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.03.2017, 23:12   #1
Homa_1983
Пользователь
 
Регистрация: 14.10.2011
Сообщений: 29
Восклицание Передача структуры с динамическим массивом между процессами

Доброго всем времени суток!

Нужно передать структуру от одного процесса другому (суть между двумя не связанными программами). Делаю через FileMapping.
Если структура содержит массивы фиксированной длины, то все замечательно работает. Вот рабочий код:

Struct.h - общий для Process1.cpp и Process2.cpp
Код:
#ifndef StructH
#define StructH

typedef struct {
	char NamesOfParam[50];
	double DataArray[100];
}MyStruct, *pMyStruct;
#endif
Process1.cpp
Код:
...
#include <Struct.h>

TCHAR MapFileName[]=TEXT("DataMappingObject");
HANDLE hMapFile;

pMyStruct pBuf;

...
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,    // use paging file
				     NULL,                    // default security
				     PAGE_READWRITE,          // read/write access
				     0,                       // max. object size
				     2000,                    // buffer size	(с запасом)
				     MapFileName);      // name of mapping object

if (hMapFile == NULL)
{
   AnsiString msg = "Could not create file mapping object";
   ShowMessage(msg);
   GetLastError();
}

pBuf =  (MyStruct*)MapViewOfFile(hMapFile,  	      // handle to map object
					 FILE_MAP_ALL_ACCESS, // read/write permission
					 0,
					 0,
					 0);

if (pBuf == NULL)
{
   AnsiString msg = "Could not map view of file";
   ShowMessage(msg);
   GetLastError();
}

...

double Asg[100];
memset(Asg,0,sizeof(Asg));

for( int i=0; i<100; i++)
{
   Asg[i] = random(10);
}

AnsiString Names = "bla-bla-bla";
strcpy(pBuf->NamesOfParam, Nnames.c_str());
CopyMemory(pBuf->DataArray, Asg, sizeof(Asg));

...
Process2.cpp (адресат - должен данные забирать)
Код:
...
#include <Struct.h>

TCHAR MapFileName[]=TEXT("DataMappingObject");
HANDLE hMapFile;

pMyStruct pBuf;
	
...

hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,   // read/write access
				   FALSE,                 // do not inherit the name
				   MapFileName);  // name of mapping object

if (hMapFile == NULL)
{
   AnsiString msg = "Could not create file mapping object";
   ShowMessage(msg);
   GetLastError();
}

pBuf = (pMyStruct)MapViewOfFile(hMapFile,
					FILE_MAP_ALL_ACCESS,
					0,
					0,
					0);

if (pBuf == NULL)
{
   AnsiString msg = "Could not map view of file";
   ShowMessage(msg);
   GetLastError();
}

...

Series1->Clear();

Series1->AddArray(pBuf->DataArray,100);	//,clYellow);

...
Когда пытаюсь динамически выделить память под массив структуры DataArray, то работа нарушается.
Ниже привожу реализацию кода:

Struct.h - общий для Process1.cpp и Process2.cpp
Код:
#ifndef StructH
#define StructH

typedef struct {
	char NamesOfParam[50];
	double* DataArray;            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}MyStruct, *pMyStruct;
#endif
Process1.cpp
Код:
...
#include <Struct.h>

TCHAR MapFileName[]=TEXT("DataMappingObject");
HANDLE hMapFile;

pMyStruct pBuf;

...
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,    // use paging file
				     NULL,                    // default security
				     PAGE_READWRITE,          // read/write access
				     0,                       // max. object size
				     2000,                    // buffer size	(с запасом)
				     MapFileName);      // name of mapping object

if (hMapFile == NULL)
{
   AnsiString msg = "Could not create file mapping object";
   ShowMessage(msg);
   GetLastError();
}

pBuf =  (MyStruct*)MapViewOfFile(hMapFile,  	      // handle to map object
					 FILE_MAP_ALL_ACCESS, // read/write permission
					 0,
					 0,
					 0);

if (pBuf == NULL)
{
   AnsiString msg = "Could not map view of file";
   ShowMessage(msg);
   GetLastError();
}

pBuf->DataArray = new double[100];             !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! (высвобождение памяти происходит при закрытии приложения, здесь в коде не показано)
...

double Asg[100];
memset(Asg,0,sizeof(Asg));

for( int i=0; i<100; i++)
{
   Asg[i] = random(10);
}

AnsiString Names = "bla-bla-bla";
strcpy(pBuf->NamesOfParam, Nnames.c_str());
CopyMemory(pBuf->DataArray, Asg, sizeof(Asg));

...
Память выделяется, данные копируются, все ок. Но вот второй процесс не видит динамического массива. Т.е. массив pBuf->NamesOfParam виден, все ок. А вот массив pBuf->DataArray в нулях...
Реализация Process2.cpp не изменилась:
Код:
...
#include <Struct.h>

TCHAR MapFileName[]=TEXT("DataMappingObject");
HANDLE hMapFile;

pMyStruct pBuf;
	
...

hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,   // read/write access
				   FALSE,                 // do not inherit the name
				   MapFileName);  // name of mapping object

if (hMapFile == NULL)
{
   AnsiString msg = "Could not create file mapping object";
   ShowMessage(msg);
   GetLastError();
}

pBuf = (pMyStruct)MapViewOfFile(hMapFile,
					FILE_MAP_ALL_ACCESS,
					0,
					0,
					0);

if (pBuf == NULL)
{
   AnsiString msg = "Could not map view of file";
   ShowMessage(msg);
   GetLastError();
}

...

Series1->Clear();

Series1->AddArray(pBuf->DataArray,100);	//,clYellow);

...
Собственно у меня несколько вопросов:
1. Почему Process2 перестает видеть данные массива pBuf->DataArray если память для него выделяется динамически?
1. Надо ли как-нибудь дополнительно описывать массив DataArray в Process2? С одной стороны, мне казалось, что если память под него выделена в Process1, то с помощью MapViewOfFile в Process2 я должен иметь возможность все просматривать. С другой стороны, понятно, что Process2 (из Struct.h) знает только вид структуры и то, что вторым ее элементом является указатель на тип double, больше ничего... Как тогда правильно сделать?

Пожалуйста, помогите разобраться

Последний раз редактировалось Homa_1983; 29.03.2017 в 23:59.
Homa_1983 вне форума Ответить с цитированием
Старый 30.03.2017, 02:59   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Почему Process2 перестает видеть данные массива pBuf->DataArray если память для него выделяется динамически?
Потому что она выделяется в адресном пространстве процесса1

Цитата:
Надо ли как-нибудь дополнительно описывать массив DataArray в Process2? С одной стороны, мне казалось, что если память под него выделена в Process1, то с помощью MapViewOfFile в Process2 я должен иметь возможность все просматривать.
Рассматривайте проекцию как файл, даже по названию понятно... Если в файл вы запишите только указатели, то потом хоть обсчитывайте этим файлом.
p51x вне форума Ответить с цитированием
Старый 30.03.2017, 21:06   #3
Homa_1983
Пользователь
 
Регистрация: 14.10.2011
Сообщений: 29
По умолчанию

Цитата:
Потому что она выделяется в адресном пространстве процесса1
Так ведь она в любом случае выделяется в адресном пространстве процесса1. И когда массив фиксированный, и когда динамический.. Разве это не так?
А MapViewOfFile лишь связывает проекцию с адресным пространсвом процесса через указатель. Поэтому какая разница какой массив по сути? Я вот этого не понимаю

Цитата:
...Если в файл вы запишите только указатели, то потом хоть обсчитывайте этим файлом.
Простите, но тут я не понял, что имеется в виду. Можно по подробнее?
Homa_1983 вне форума Ответить с цитированием
Старый 30.03.2017, 21:19   #4
Homa_1983
Пользователь
 
Регистрация: 14.10.2011
Сообщений: 29
По умолчанию

Цитата:
Потому что она выделяется в адресном пространстве процесса1
Или тут имелось в виду, что в случае моей реализации Process2, где описан только указатель double* DataArray, этот самый указатель вовсе не обязан указывать на начало масcива Datarray в отображении?

Последний раз редактировалось Homa_1983; 30.03.2017 в 21:25.
Homa_1983 вне форума Ответить с цитированием
Старый 31.03.2017, 06:04   #5
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Простите, но тут я не понял, что имеется в виду. Можно по подробнее?
Куда уж подробнее... Давайте упрощено:
Проекция это файл, расположеный с 0 до 150 адреса. И, естественно, в процессе2 замаплены адреса от 0 до 150. Теперь вы пишите туда указатель на линамическую память с 1110 адреса, где процесс2 ее возьмет?

Если не понятно, рпедставьте, что у вас общение не в реальном режиме. Просто первый1 процесс записывает реальный файл на диск, закрывается, а потом второй процесс2 читает его с диска...
p51x вне форума Ответить с цитированием
Старый 31.03.2017, 11:02   #6
Homa_1983
Пользователь
 
Регистрация: 14.10.2011
Сообщений: 29
По умолчанию

Понял. Спасибо.
Homa_1983 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Взаимодействие между процессами. JPCool Win Api 2 23.01.2016 18:26
Взаимодействие между процессами СветОК Операционные системы общие вопросы 0 17.12.2012 16:06
Проблемма с динамическим массивом Arassir Помощь студентам 3 15.02.2009 12:37
Разница между динамическим массивом и нединамическим. Stager Общие вопросы C/C++ 1 05.01.2009 22:32
Работа с динамическим массивом sand Общие вопросы C/C++ 3 22.08.2008 12:48