问题
My application is executing another process ("update.exe"), and I would like to pass large data (a Record maybe) from my app to the update program.
Using command line to pass the data parameter(s) is not an option, because the data is too big (also Data size may vary).
How to correctly create CreateFileMapping
/MapViewOfFile
/UnmapViewOfFile
,
then Executing my update.exe,
finally Receiving the data in the update.exe program (OpenFileMapping
),
and freeing all handles (from main app and update.exe) so I don't have memory/handle leaks?
Code would be nice (No JCL
please). C++ is also fine.
Thanks.
Edit: I think my main problem is how to "signal" the main app to UnmapViewOfFile
and CloseHandle
after update.exe
done reading the data. (or maybe I need to use OpenFileMapping
with bInheritHandle
set to True
in my child process?)
Here is an Example. How can the Second process read the data if the main process calls UnmapViewOfFile
and CloseHandle
?.
回答1:
You may find some good example at Inter-process communication. Right method depends on the size of your data and speed requirements.
回答2:
Heres a code snippet from a memory mapped file we use to pass live video (uncompressed) between our applications, the SecurityDescriptor isn't needed but i've left it in and CreateWorldAccessDescriptor is one of our functions.
If you need to use this type of system to control messaging from services to application, or from applications running with different user credentials make sure you start your FileName with "Global\"
procedure TRawFeedImageQueue.CreateFileMap;
var
SysInfo: TSystemInfo;
sd: TSecurityDescriptor;
begin
GetSystemInfo( SysInfo );
MapGranularity := SysInfo.dwAllocationGranularity;
MapSize := sizeof( TRawFeedImageQueueData );
FSecObjOk := CreateWorldAccessDescriptor( sd, GENERIC_ALL );
FileMappingHandle := CreateFileMapping( $FFFFFFFF, @sd, PAGE_READWRITE OR SEC_COMMIT, 0, MapSize and $FFFFFFFF, PChar(FFileName) );
if FileMappingHandle <> 0 then
begin
MapView := MapViewOfFile( FileMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, MapSize );
end
else
begin
MapView := nil;
end;
end;
procedure TRawFeedImageQueue.ReleaseFileMap;
begin
if FileMappingHandle <> 0 then
begin
unMapViewOfFile( MapView );
CloseHandle( FileMappingHandle );
end;
end;
Hope that helps a bit.
Update
This code simply creates a MapView on the file of the whole file, and just a single view, you can of course create multiple smaller views on the same file if required.
来源:https://stackoverflow.com/questions/9381525/how-to-correctly-use-file-mapping-and-pass-data-to-a-child-process