Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблемы с разделяемой памятью [D6]


Homesad ©   (2005-02-04 14:04:00) 

Ребята, нужна помощь.
Вобщем надо чтобы две копии одного консольного процесса,
имели доступ по записи к общему участку памяти.
Программу я писал на VirtualPascale. (ОС - Windows 2003 Server).
Тот фрагмент который вызывает проблему я для простоты
переписал на Delphi 6. Вот полный ее текст.

{$APPTYPE CONSOLE}
uses Windows,SysUtils;
VAR Api,nApi : Pointer;
   hApi,nhApi :word;
   ApiName  : Pchar;

Begin
ApiName:='Test';
hApi:=CreateFileMapping($FFFFFFFF,Nil,PAGE_READWRITE,0,1,ApiName);
writeln(GetLastError,' - ',hApi);
Api:=MapViewOfFile(hApi,FILE_MAP_READ or FILE_MAP_WRITE,0,0,0);
writeln(GetLastError,' - ',Dword(Api));
readln;
nhApi:=OpenFileMapping(PAGE_READWRITE,false,ApiName);
writeln(GetLastError,' - ',nhApi);
nApi:=MapViewOfFile(nhApi,FILE_MAP_READ or FILE_MAP_WRITE,0,0,0); // !!!!!!!!!!!!!!!
writeln(GetLastError,' - ',Dword(nApi));
readln;
UnMapViewOfFile(nApi);
CloseHandle(nhApi);
UnMapViewOfFile(Api);
CloseHandle(hApi);
End.

После строчки с восклицательными знаками,
GetLastError = 5 - доступ запрещен.
Если оставляю только параметр FILE_MAP_READ, то
все в порядке, но ведь мне запись в общую память нужна!!!
Вроде все делаю как написано, вобщем я в тупике, подскажите
что не так. Или может посоветуете какой-нибудь другой способ,
обмена данными между двумя процессами ???


Homesad   (2005-02-04 23:31:00) [1]

Огромное спасибо BlackTr

nhApi:=CreateFileMapping($FFFFFFFF,Nil,PAGE_READWRITE,0,1,ApiName);
Дало тот результат который мне нужен.

>> По коду у тебя один процесс :)
Да по коду у меня один процесс, но это я сделал для отладки.
На самом деле это консольная программа, для приема-передачи
гидрометеоинформации по COM-порту. Скорость обычно 100-200 бод.
Первая копия запускается и работает если выражатся терминами
DOS в резидентном режиме, обеспечивая прием данных, и в том
числе создает обьект разделяемой памяти. Вторая копия программы
запущенная из любого файл-менеджера с определенными ключами,
передает указанный в параметрах файл 1-й копии для его передачи
в канал, вот для чего мне нужна была Ваша помощь.
Вобщем еще раз огромное спасибо, а то не мог продолжить работу,
над этим нужным проектом для нашей сети гидрометеостанций.
Родина Вас не забудет, (меня может быть тоже :-) ).
Я работаю на острове Диксон, нам всего три месяца назад дали,
доступ в инет, наверное севернее его уже нигде нет,канал очень
слабенький 14 kbs и меньше, но это уже все таки что-то.
Десять лет работать здесь и только лишь знать (но не видеть
и не использовать все преимущества доступа в инет) это для
человека связанного с компьютерами почти пытка.
Простите что так много всего наговорил, просто эмоции подкатили.
Еще задам маленький вопрос, это уже не срочно, так мне для
общего развития, можно и если да то как из консольного окна
вызвать функцию GetOpenFileName, так чтобы она выскакивала
на передний план, а то она выходит где-то под другими окнами.
С функцией MessageBox у меня тоже так было пока я флаг
MB_SYSTEMMODAL не поставил.


Piter   (2005-02-04 19:03:00) [2]

Игорь Шевченко ©   (04.02.05 17:07) [8]
> попробуй вместо этого FILE_MAP_ALL_ACCESS

И нафига, собственно ?


да я только предположил. Просто бегло взглянув на file_map_all_access, увидел достаточно сложную комбинацию флагов:

(STANDARD_RIGHTS_REQUIRED or SECTION_QUERY or
   SECTION_MAP_WRITE or SECTION_MAP_READ or SECTION_MAP_EXECUTE or SECTION_EXTEND_SIZE);


а не просто чтение/запись/выполнение. поэтому и подумалось - вдруг в этом дело... это было всего лишь предположение...


alpet   (2005-02-04 18:01:00) [3]

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


BlackTr   (2005-02-04 17:44:00) [4]

Подумал, а почему OpenFileMapping неработает ?
Только счас дошло:
должно быть не nhApi:=OpenFileMapping(PAGE_READWRITE,false,ApiName);
а nhApi:=OpenFileMapping(FILE_MAP_READ or FILE_MAP_WRITE,false,ApiName);
:)))


alpet   (2005-02-04 17:32:00) [5]

[i]Так, что OpenFileMapping нафиг не нужен :)[/i]
Точно. Я весьма не внимателен :-(


BiN   (2005-02-04 17:29:00) [6]

Проблема налицо - в MapViewOfFile передается неверное значение описателя MMF по причине, указанной Piter-ом в первой части [6]


BlackTr   (2005-02-04 17:25:00) [7]


> Если ее создать дважды последняя попытка провалится, как
> написано в MSDN: If the object existed before the function
> call, the function returns a handle to the existing object
> (with its current size, not the specified size) and GetLastError
> returns ERROR_ALREADY_EXISTS.


Сам хоть понял, что тут написано ???
Если существует, то вернет handle существующего...
Так, что OpenFileMapping нафиг не нужен :)


alpet   (2005-02-04 17:23:00) [8]

Почему сразу не сделать CreateFileMapping?
Два одинковых процесса смогут использовать проекцию, если открывать ее с помощью OpenFileMapping.
Если ее создать дважды последняя попытка провалится, как написано в MSDN: If the object existed before the function call, the function returns a handle to the existing object (with its current size, not the specified size) and GetLastError returns ERROR_ALREADY_EXISTS.


Игорь Шевченко   (2005-02-04 17:07:00) [9]

Piter ©   (04.02.05 16:40) [6]


> попробуй вместо этого FILE_MAP_ALL_ACCESS


И нафига, собственно ?


Piter   (2005-02-04 17:00:00) [10]

alpet   (04.02.05 16:33) [5]
Если планируется запускать несколько копий одного процесса, сначала вызывается OpenFileMapping, и если она возвращает ошибку вызвается CreateFileMapping


зачем? Почему сразу не сделать CreateFileMapping?


Piter   (2005-02-04 16:40:00) [11]

Homesad ©   (04.02.05 14:04)
hApi,nhApi : word;


не word, а DWORD должен быть. Непонятно, как компилятор не удивляется

Homesad ©   (04.02.05 14:04)
Api:=MapViewOfFile(hApi, FILE_MAP_READ or FILE_MAP_WRITE,0,0,0);


попробуй вместо этого FILE_MAP_ALL_ACCESS

Homesad ©   (04.02.05 14:04)
nhApi:=OpenFileMapping(PAGE_READWRITE,false,ApiName);
writeln(GetLastError,' - ',nhApi);
nApi:=MapViewOfFile(nhApi,FILE_MAP_READ or FILE_MAP_WRITE,0,0,0); // !!!!!!!!!!!!!!!


а это строчки зачем? Ты хоть бы справку почитал про CreateFileMapping:

"The handle that CreateFileMapping returns has full access to the new file-mapping object"

Не нужно никакого OpenFileMapping после этого...


alpet   (2005-02-04 16:33:00) [12]

Если планируется запускать несколько копий одного процесса, сначала вызывается OpenFileMapping, и если она возвращает ошибку вызвается CreateFileMapping, и только потом MapViewOfFile.


BlackTr   (2005-02-04 15:04:00) [13]


> nhApi:=OpenFileMapping(PAGE_READWRITE,false,ApiName);

nhApi:=CreateFileMapping($FFFFFFFF,Nil,PAGE_READWRITE,0,1,ApiName);
и все должно работать...


> обмена данными между двумя процессами ???

По коду у тебя один процесс :)


Digitman   (2005-02-04 14:29:00) [14]


> Или может посоветуете какой-нибудь другой способ,
> обмена данными между двумя процессами ???


посоветую.
Named Pipes этот "способ" зовется


Игорь Шевченко   (2005-02-04 14:21:00) [15]

Program Files\Borland\Delphi\Demos\IpcDemos\*.*


Eraser   (2005-02-04 14:11:00) [16]

Homesad ©
Или может посоветуете какой-нибудь другой способ,
обмена данными между двумя процессами


Какого плана у тебя приложение? Может ли в обозимом будущем возникнуть необходимость разделения этих процессов на разные машины?
Какое кол-во данных передаётся (много/мало (кб/с))?


Наверх

Титульная страница Поиск, карта сайта Написать письмо