Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> FileMapping-передать класс другому процессу, А ну -ка шляньте,опять где-то туплю 
:(
    Опции темы
Coocky
Дата 22.3.2007, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: нет
Всего: 62



Понадобилось использовать файл мэппинг для работы. Ни разу раньше не пользовался. А вот "с налету" не получилось.. smile 
И так, есть класс
Код

class Info
{
public:
  Info(){NewNameFile=new WCHAR [1024];OldFileName=new WCHAR [1024];FileName=new WCHAR [1024];}
  ~Info(){delete []NewNameFile;delete[] OldFileName;delete[] FileName;}
  WCHAR *NewNameFile ;
  WCHAR *OldFileName ;
  WCHAR *FileName ;
  int name_op;
};


Нужно его передать другому процессу
Код

  Info* lpData=NULL;
  Info *inf=new Info;
  
  wcscpy(inf->OldFileName,lpExistingFileName);
  wcscpy(inf->NewNameFile,lpNewFileName);

  inf->name_op=MOVE_FILE;

  if (hMapping != NULL) 

  {

    lpData = (Info*) MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS,0,0,0);
    memcpy ( lpData ,inf,sizeof(Info));
    UnmapViewOfFile(lpData);
}
    delete inf;



на выходе п другом процессе

Код

Info*lpData=NULL;
  Info *inf=new Info;
  lpData = (Info*) MapViewOfFile(hMapping2, FILE_MAP_ALL_ACCESS,0,0,0);
  if (lpData!=NULL) 
  {
    memcpy(inf,lpData,sizeof(Info));
    ZeroMemory(lpData,10024);
    UnmapViewOfFile(lpData);
  }
  delete inf;


Ну и естествено все даные неправильные ,короче лабуда. Одна.. Где протупил?

Добавлено @ 13:19 
Да, забыл сказать, до этого передавал просто строку.. тренировался. Все работало. А  с классом не получается.. 


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Pulse69
Дата 22.3.2007, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 28.4.2006
Где: Хабаровск

Репутация: 8
Всего: 10



Вот самое простое, что приходит на ум:

Цитата(Coocky @  22.3.2007,  13:18 Найти цитируемый пост)
  
WCHAR *NewNameFile ;  
WCHAR *OldFileName ;  
WCHAR *FileName ;


В одном процессе данные указатели абсолютно корректны и указывают на выделенный
участок памяти. Когда Вы передаёте класс другому процессу, данные указатели теряют
свой смысл, так как в контексте второго процесса указывают на абсолютно непонятную область памяти.
Если объявить эти же переменные как 
WCHAR variable_name[1024], всё должно работать правильно, так как в этом случае 
другому процессу будет полностью передан этот блок памяти.

Это сообщение отредактировал(а) Pulse69 - 22.3.2007, 15:30
--------------------
Ctrl+Alt+Reset 
PM MAIL   Вверх
Coocky
Дата 22.3.2007, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: нет
Всего: 62



Pulse69, 
Цитата(Pulse69 @  22.3.2007,  15:29 Найти цитируемый пост)
свой смысл, так как в контексте второго процесса указывают на абсолютно непонятную область памяти.Если объявить эти же переменные как WCHAR variable_name[1024], всё должно работать правильно, так как в этом случае другому процессу будет полностью передан этот блок памяти.

Это был самый первый вариант. Я просто подумал, что стоит оперировать с указателями. Страно. Но только что все переделал, снова под 
Код

class Info
{
public:
  WCHAR NewNameFile [1024] ;
  WCHAR OldFileName [1024];
  WCHAR FileName [1024] ;
  int name_op;
};


Теперь работает.. Ничего не пойму.. Но это уже мои проблемы.. Где-то что-то когда-то потерял.. smile В любому случае спасибо smile

Добавлено @ 15:42 
Интересно, а если понадобится работа с указателями (ну там память выделить нужно будет), как тогда быть? Разыименование?



--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Pulse69
Дата 22.3.2007, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 28.4.2006
Где: Хабаровск

Репутация: 8
Всего: 10



Просто поймите что именно Вы делали своим первым кодом.

1.    Создаёте указатель на данные (пусть будет m_pData).

2.    Выделяете память m_pData = new WCHAR[1024]. Т.е. в куче ПЕРВОГО процесса был 
выделен 1кБ памяти.

3.    Передаёте УКАЗАТЕЛЬ ВТОРОМУ процессу. То есть Вы физически передали 4 байта - sizeof(m_pData) 
второму процессу. m_pData указывает на адрес в виртуальном пространстве ПЕРВОГО процесса. По этому
адресу у ВТОРОГО процесса может располагаться всё что угодно. Сами же данные остались в первом
процессе, где они, естественно, имеют смысл. 

В втором же случае (статические массивы) Вы физически передаёте из 1го процесса 2му 1кБ данных
(текст), поэтому 2й процесс их может спокойно использовать.

Проще говоря, нельзя передавать адрес в одном процессе другому. Все данные необходимо копировать
в Ваше отображение.

Надеюсь, теперь всё ясноsmile


Это сообщение отредактировал(а) Pulse69 - 22.3.2007, 15:50
--------------------
Ctrl+Alt+Reset 
PM MAIL   Вверх
Coocky
Дата 22.3.2007, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: нет
Всего: 62



Цитата(Coocky @  22.3.2007,  15:39 Найти цитируемый пост)
 Но это уже мои проблемы.. Где-то что-то когда-то потерял.. 

 Уже не вспомню, но вроде как делал так 
Код

  memcpy ( lpData ,&inf,sizeof(Info));


т.е. передавал ссылку на обьект,без выделения памяти. Вроде поэтому не работало с
  WCHAR NewNameFile [1024] ;
  WCHAR OldFileName [1024];
  WCHAR FileName [1024] ;

Добавлено @ 15:54 
Цитата(Pulse69 @  22.3.2007,  15:48 Найти цитируемый пост)
Просто поймите что именно Вы делали своим первым кодом.

Так в том то и дело, что первый код был без указателей WCHAR (я ленивый человек, и мне неохота было писать конструктор для выделения памяти). Но Этот вариант не сработал тоже (я и говорю - страно.... smile )
Не имея понятия о ФайлМепинге -я решил , что может стоить оперировать с указателями, хотя прекрасно понимаю, что это не сработает в разных процессах. Вообщем, где-то в первом коде ошибся-и полетело,понесло... Вообще растерялся даже.. Ну теперь все на своих местах.

Это сообщение отредактировал(а) Coocky - 22.3.2007, 15:50


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
maxim1000
Дата 22.3.2007, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 2
Всего: 110



кстати, можно было бы попробовать такой вариант:
все объекты хранить в области памяти, занятой оторбажаемым файлом
ну и при передаче все указатели преобразовывать, чтобы сохранялась разница указателя на данные и указателя на начало памяти файла


--------------------
qqq
PM WWW   Вверх
Coocky
Дата 22.3.2007, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: нет
Всего: 62



Цитата(maxim1000 @  22.3.2007,  17:02 Найти цитируемый пост)
кстати, можно было бы попробовать такой вариант:все объекты хранить в области памяти, занятой оторбажаемым файлом

А смысл? Или я что -то не понял..  Можно немного пдробней. Я всего час юзаю этот мапфайл smile 




--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
maxim1000
Дата 22.3.2007, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 2
Всего: 110



Цитата(Coocky @  22.3.2007,  16:09 Найти цитируемый пост)
Я всего час юзаю этот мапфайл

я его вообще ни разу не использовал smile

смысл в том, что map file позволяет иметь в двух процессах общую область
адреса её начала для каждого процесса чаще всего будут разными, но если какая-то ячейка для одного процесса стоит через 10 байт после начала области map файла, то и в другом процессе эта разница сохранится

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

единственная проблема, которую я вижу - классы с виртуальными методами:
1. сами виртуальные таблицы и методами вряд ли удастся расположиться в map file (это вообще страшно как-то)
2. мы не контролируем тип указателя на таблицу виртуальных методов, он вседа абсолютный

так что способ этот подходит для классов без виртуальных методов...


--------------------
qqq
PM WWW   Вверх
Pulse69
Дата 23.3.2007, 00:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 28.4.2006
Где: Хабаровск

Репутация: 8
Всего: 10



Мне лично кажется, что это всё будет какое-то шаманство. 
Лучше не разделять экземпляр класса между процессами,
а написать класс, который внутри будет использовать 
Mapped file во внутренней реализации, а все данные получать из 
него с помощью методов класса. Тогда каждый процесс будет иметь свой
экземпляр объекта и не будет таких проблем с относительными
указателями, виртуальными методами и статическими переменными класса.
--------------------
Ctrl+Alt+Reset 
PM MAIL   Вверх
Earnest
Дата 23.3.2007, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(maxim1000 @  22.3.2007,  19:51 Найти цитируемый пост)
единственная проблема, которую я вижу - классы с виртуальными методами:

не единственная: тоже самое относится к динамиччески выделяемой памяти внутри класса - она-то будет использовать хип. Да тот же CString.
Другими словами, полноценный класс в маппинг не засунешь, или надо поиметь много геморроя и специально конструировать класс под такое использование: не стоит оно того.

Pulse69 прав: не надо путать суп с мухами. Через маппинг можно передать данные - просто сериализовать. Но тоже самое можно сделать с помощью WM_COPYDATA, а также другими способами.
Я использую файл-маппинг в двух случаях: когда надо читать большие файлы сложной структуры (возможно даже с произвольным доступом) - отображение в память позволяет обойтись без всяких fseek и прочая - память она и  есть память. Особенно, если все влезает в один View.
Второй случай - при работе с очень большими данными - когда несчасного 1 гб может не хватить -например, при развертывании в памяти очень больших растров.


--------------------
...
PM   Вверх
SenkraD
Дата 23.3.2007, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 4
Всего: 23



если надо работать с указателями с мап-файлами, то почитай о базовых указателях.
Они, в принципе, предназначены для работы с мап-файлами.


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1120 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.