Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2003.07.21;
Скачать: [xml.tar.bz2];

Вниз

Непонятное поведение MMF при использовании файла страничного обм.   Найти похожие ветки 

 
Anna Samoilova   (2003-05-20 10:34) [0]

Здравствуйте, многоуважаемые.
У меня такой конфуз вчера случился: создаю именованный объект файлового отображения отображаю данные на АП своего процесса – всё прекрасно!
НО, когда пытаюсь получить доступ к этому именованному объекту из любого другого процесса или даже этого самого, то и OpenFileMapping и CreateFileMapping возвращают handle отличающийся от того, что вернула мне CreateFileMapping при первом создании, и соответственно MapViewOfFile возвращает либо 0 либо какой-то бред.
Причём, что характерно, если я в том же процессе, где я создала объект MMF выполняю UnmapViewOfFile() и CloseHandle() а затем снова пытаюсь из любого процесса получить доступ к уже “закрытому” MFF, то и OpenFileMapping и CreateFileMapping возвращает именно тот handle, то вернула CreateFileMapping при первом вызове (т.е. при первичном создании MMF). Парадокс какой-то! Или я что-то напутала вконец (хотя раньше без проблем обеспечивала таким же образом обмен данными между DLL, находящимися в разных АП, но ведь не важно откуда я создаю MMF – из DLL или exe-файла!)
Итак, код:

// поля данной структуру буду отображать в файл подкачки
type
PInputRec = ^TInputRec;
TInputRec = record
SMyStr: string [50];
ICount: Integer;
end;

const
MMFName: PChar = "MyMMF063"; // имя объекта файлового отображения

var
GlobalData: PInputRec;
MMFHandle: HWND; // указатель на объект файлового отображения

procedure OpenGlobalData();
begin
MMFHandle:= CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TInputRec), MMFName);
if MMFHandle = 0 then
begin
MessageBox(0, PChar("Can""t create FileMapping"), PChar("My app"), 0);
Exit;
end
else
MessageBox(0, PChar(IntToStr(MMFHandle)), PChar(" My app "), 0);

GlobalData:= MapViewOfFile(MMFHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TInputRec));
if GlobalData = nil then
begin
CloseHandle(MMFHandle);
MessageBox(0, PChar("Can""t make MapViewOfFile"), PChar(" My app "), 0);
Exit;
end;
end;

procedure CloseGlobalData();
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MMFHandle);
end;

procedure InpDataToMMF();
begin
OpenGlobalData();
GlobalData^.sMyStr:= "test_My_MMF!!!";
GlobalData^.iCount:= 5;
end;


Вот такие пироги!

Вопрос вдогонку: можно ли с помощью WM_COPYDATA передавать не только строки, но и записи? (всё равно ведь через MMF делается)

Спасибо!

procedure InpDataToMMF();
begin
OpenGlobalData();
GlobalData^.SMyStr:= "test_My_MMF!!!";
GlobalData^.Icount:= 5;
end;


Вот такие пироги!

Вопрос вдогонку: можно ли с помощью WM_COPYDATA передавать не только строки, но и записи? (всё равно ведь через MMF делается)

Спасибо!


 
MBo   (2003-05-20 10:53) [1]

выглядит нормально. Handle того же объекта ядра в другом процессе будет отличаться. Если он не нулевой, то это никак не должно повлиять на MapView.

CreateFileMapping(..., PChar(MMFName)); не поможет?


>Вопрос вдогонку
Да.


 
Anna Samoilova   (2003-05-20 10:59) [2]

>>MBo © (20.05.03 10:53):
CreateFileMapping(..., PChar(MMFName)); не поможет?

см. выше:

const
MMFName: PChar = "MyMMF063";


Вот и я не пойму в чём дело. Даже если handle будет другой в другом процессе, то ведь всё равно не работает как надо.
А почему, кстати, handle другой - объёкт системы же один на всех! Ведь, к примеру у окна handle всегда один и в каком бы процессе мы бы не сделали FindWindow(nil, "This window") мы получим один и тот же handle!

2. Спасибо.


 
Anna Samoilova   (2003-05-20 12:25) [3]

Sorry за повторения в первом посте - bugs not dead ;)


 
Игорь Шевченко   (2003-05-20 12:26) [4]

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


 
Anna Samoilova   (2003-05-20 12:30) [5]

>>Игорь Шевченко © (20.05.03 12:26):

У меня нет подобного примера.
Я в MSDN посмотрела - ничего особенного, у меня всё верно, вроде бы.
Если пример из Demos небольшой, не могли бы сюда его поместить, если, конечно, это не протеворечит политики данного форума?


 
Игорь Шевченко   (2003-05-20 12:51) [6]

Anna Samoilova (20.05.03 12:30)

Пример большой. Напишите на whitefranz@hotmail.com - вышлю.


 
VMcL   (2003-05-20 12:53) [7]

>Anna Samoilova (20.05.03 12:30)

Давай мыло, вышлю. У меня Delphi 6.


 
Ihor Osov'yak   (2003-05-20 12:56) [8]

Тоже с первого взгляда все нормально.
Даю работающий пример, может поможет, сделан на основании упоминаемой выше демки:


THandledObject = class(TObject)
protected
FHandle: THandle;
public
destructor Destroy; override;
property Handle: THandle read FHandle;
end;


{ TSharedMem }
{ This class simplifies the process of creating a region of shared memory.
In Win32, this is accomplished by using the CreateFileMapping and
MapViewOfFile functions. }

TSharedMem = class (THandledObject)
private
FName: string;
FSize: Integer;
FCreated: Boolean;
FFileView: Pointer;
fAccessMutex:THandle;
public
constructor Create(const Name: string; Size: Integer;
pSecurity:PSecurityAttributes = nil);

destructor Destroy; override;

function Lock(aTimeOut:integer):boolean;
function UnLock:boolean;

property Name: string read FName;
property Size: Integer read FSize;
property Buffer: Pointer read FFileView;
property Created: Boolean read FCreated;

end;

{ TSharedMem }






{ THandledObject }

destructor THandledObject.Destroy;
begin
if FHandle <> 0 then begin
CloseHandle(FHandle);
FHandle := 0;
end;

end;


constructor TSharedMem.Create(const Name: string; Size: Integer;
pSecurity: PSecurityAttributes = nil);
var flLock:boolean;
begin
try
FName := Name;
FSize := Size;

fAccessMutex := CreateMutex(pSecurity, False, PChar(Name+".m"));
if fAccessMutex = 0 then abort;

flLock := Lock(100);
try
{ CreateFileMapping, when called with $FFFFFFFF for the hanlde value,
creates a region of shared memory }
FHandle := CreateFileMapping($FFFFFFFF, pSecurity, PAGE_READWRITE, 0,
Size, PChar(Name));
if FHandle = 0 then abort;

FCreated := GetLastError = 0;
{ We still need to map a pointer to the handle of the shared memory region }
FFileView := MapViewOfFile(FHandle, FILE_MAP_WRITE, 0, 0, Size);
if FFileView = nil then abort;
if FCreated and flLock then FillChar(FFileView^,Size,0);
finally
if flLock then UnLock;
end;
//if FCreated then
except
Error(Format("Error creating TSharedMemory %s (%d)", [Name, GetLastError]));
end;
end;

destructor TSharedMem.Destroy;
begin
if FFileView <> nil then
UnmapViewOfFile(FFileView);
if fAccessMutex <> 0 then CloseHandle(fAccessMutex);
inherited Destroy;
end;




function TSharedMem.Lock(aTimeOut: integer):boolean;
begin
Result := WaitForSingleObject(fAccessMutex, aTimeOut) = WAIT_OBJECT_0;
end;

function TSharedMem.UnLock:boolean;
begin
Result := ReleaseMutex(fAccessMutex);
end;



Как видишь, единственное различие - если отображение создается - то оно обнуляется, для случая открітия уже созданого - ничего не делаем. Плюс использования мьютекса для арбитража доступа..

Пример использования:

procedure OpenSharedObject(aCallBack:TIPCEventReceiverCallBack);

var
sd: TSecurityDescriptor;
sa: TSecurityAttributes;
lpsa: PSecurityAttributes;

begin

lpsa := nil;
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin

ZeroMemory(@sd, SizeOf(sd));
ZeroMemory(@sa, SizeOf(sa));

// set security for NT platforms
InitializeSecurityDescriptor(@sd, 1);
SetSecurityDescriptorDacl(@sd, True, nil, False);
sa.nLength := SizeOf(TSecurityAttributes);
sa.bInheritHandle := True;
sa.lpSecurityDescriptor := @sd;
lpsa := @sa;
end;

sSharedMem := TSharedMem.Create(sharedDataSign,sizeof(TSharedData),lpsa);
sIPCSender := TIPCEventSender.Create(notifFromSrvToConf_EventSign,lpsa);
sIPCReceiver :=TIPCEventReceiver.Create(aCallBack,0,notifFromConfToSrv_EventSign);


end;

procedure CloseSharedObject;
begin
if assigned(sSharedMem) then sSharedMem.Free;
if assigned(sIPCSender) then sIPCSender.Free;
if assigned(sIPCReceiver) then sIPCReceiver.Free;
sSharedMem := nil;
sIPCSender := nil;
sIPCReceiver := nil;
end;





procedure TFormSetStoragePrm.AfterConstruction;
var pSD:PSharedData;

begin
inherited;
lbWarning.Caption := "";
if sSharedMem.Lock(50) then begin
pSD:= sSharedMem.Buffer;

with pSD^...


sSharedMem.Unlock;
end


end;



Зы - используй более творческие имена, чем "MyMMF063"

К примеру, чего-то на основании GUI -

sharedDataSign = "237752D9-33A5-4B1E-92F9-6D1FAC659896"; { This string used as
the base for names of system objects (events,mutex, FMM) that are using for IPC
between the Service and the Configurator (FileStorageManager.exe)
}





 
VMcL   (2003-05-20 13:04) [9]

>Ihor Osov"yak © (20.05.03 12:56)

В смысле не "GUI", а "GUID" :)


 
Ihor Osov'yak   (2003-05-20 13:07) [10]

2 VMcL © (20.05.03 13:04)

Ну да, сорри .. Ctrl_Shift_G ...


 
MBo   (2003-05-20 13:59) [11]

> почему, кстати, handle другой - объект системы же один на всех
Так устроена система ради безопасности - одинаковые в каждом процессе дескрипторы позволили бы внедряться друг в друга. Отдельное ВАП (вирт. адресное пространство) каждого процесса тоже для повышения устойчивости системы.


 
Anna Samoilova   (2003-05-20 14:53) [12]

Всем спасибо. Пример нашла.

А вам, народ, не очень ленностно мой вариант попробовать - у вас тот же эффект будет или нет - просто интерестно?


 
nikkie   (2003-05-20 15:28) [13]

>у вас тот же эффект будет или нет
у меня (D6 + Win2k) твой код работает, значение хендла одно и то же в разных процессах.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2003.07.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.008 c
1-67773
Rulja
2003-07-09 08:33
2003.07.21
Перенос клиента


14-68027
Klot
2003-07-04 18:43
2003.07.21
Настройка среды


1-67881
maxic
2003-07-08 11:02
2003.07.21
Изображение на компоненте при его создании


3-67698
SCORPION ZP
2003-06-24 11:43
2003.07.21
Реструктурирование таблиц dBASE программным путем


3-67723
APTEMKA
2003-06-27 16:22
2003.07.21
плз нужно запустить приложение на компе без BDE





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский