Board index » delphi » sharing memory mapped bitmaps

sharing memory mapped bitmaps


2003-09-05 08:15:09 AM
delphi10
hello,
Does anyone know of an example of sharing DIBs using memory mapped files? I
want to send a series of bitmaps from my Delphi application to my Delphi
DLL.
This code from another message thread somewhere seems to work in setting up
the MMF in my application although I have no idea how to reference it
afterwards in my DLL.
-----------------
var
BitmapInfoSize: Integer;
hMap: THandle;
pMap: Pointer;
MemStream: TMemoryStream;
begin
Image1.Picture.Bitmap.SaveToStream(MemStream);
BitmapInfoSize :=
PBitmapFileHeader(memstream.Memory)^.bfOffBits-SizeOf(TBitmapFileHeader);
try
hMap := CreateFileMapping($FFFFFFFF, nil,
PAGE_READWRITE,0,BitmapInfoSize,'MMBMP');
pMap := MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);
memstream.Seek(SizeOf(TBitmapFileHeader),0);
memstream.Read(pMap^,BitmapInfoSize);
finally
// unmapViewOfFile(pMap); //Disposes the mem map
CloseHandle(hMap);
end;
end;
----------------
Any advice is appreciated
Kim
ps. I posted this message though Google but it didn't show up, so apologies
if it turns up again....
 
 

Re:sharing memory mapped bitmaps

"kim" <XXXX@XXXXX.COM>writes
Quote
Does anyone know of an example of sharing DIBs using memory mapped files?
The exact same code, executed a second time, in whatever (other) process,
before you close the hMap in the original creating process, will serve you.
That is because the second CreateFileMapping call, given the same Name
'MMBMP', will return a handle to the exact same file mapping, as long as it
does already exist (as well as *still* exist, hence the need to keep at
least one reference to the memory mapped file alive by not executing the
final CloseHandle statement in the creating process untill after you're
confident the memory mapped file can be cleaned up).
The fact that this Name parameter identifies the memory mapped file accross
processes, is a good reason to choose a more elaborate unique-ish name.
Especially do not pick a name right from an example that you found on the
net. Chances are that you code will eventually run on a machine where this
name already has a meaning, probably because someone else found that example
too. It is custom to let the name start with the name of you company, and
continue with the name of the product, and next finalize with a functional
name part.
Quote
I
want to send a series of bitmaps from my Delphi application to my Delphi
DLL.
If this DLL is running in the context of your application, you already share
all memory, and there is no need to use memory mapped files. But you already
knew that, of course, sorry to point out the obvious.
Joris
 

Re:sharing memory mapped bitmaps

"kim" <XXXX@XXXXX.COM>writes
Quote
Thanks for the advice, I understand what you're saying although I still
haven't succeeded in getting the bitmap data from the memory map and back
into a TImage.

I just get an 'Invalid Bitmap Image' exception error when I try e.g:
Image2.Picture.LoadFromStream(memstream);
Post the code. If you want to go and explore such errors, first thing to do
is to (trace and evaluate/modify, or otherwise output and) compare the first
few bytes of the mapped view in each process. If these are not the same, you
know that the problem is related to the memory mapped file code. If they
are, you can guess it probably is not.
Quote
I'm also a bit confused as to why you suggest I should use
CreateFileMapping
to read back the stream, wouldn't OpenFileMapping be right for that?
- CreateFileMapping with new name, unknown to the system: Creates a new file
mapping
- CreateFileMapping with an existing memory mapped file name known to the
system: Opens a new handle to the existing file mapping
- OpenFileMapping with a new name, unknow to the system: Returns an error
- OpenFileMapping with an existing memory mapped file name known to the
system: Opens a new handle to the existing file mapping
Yes, you could use OpenFileMapping, but you can equally use
CreateFileMapping with an existing memory mapped file name. It boils down to
exactly the same operation.
<Quote from win32.hlp on CreateFileMapping>
lpName
Points to a null-terminated string specifying the name of the mapping
object. The name can contain any character except the backslash character
(\).
If this parameter matches the name of an existing named mapping object, the
function requests access to the mapping object with the protection specified
by flProtect.
If this parameter is NULL, the mapping object is created without a name.
Return Values
If the function succeeds, the return value is a handle to the file-mapping
object. If the object existed before the function call, the GetLastError
function returns ERROR_ALREADY_EXISTS, and the return value is a valid
handle to the existing file-mapping object (with its current size, not the
new specified size. If the mapping object did not exist, GetLastError
returns zero.
If the function fails, the return value is NULL. To get extended error
information, call GetLastError.
<End quote>
Joris
 

Re:sharing memory mapped bitmaps

To me, this sounds like the trap so many of us fall in:
Add
memstream.position := 0;
right before
Image2.Picture.LoadFromStream(memstream);
Hope that helps
Nils Haeck
www.simdesign.nl
"kim" <XXXX@XXXXX.COM>writes
Quote


Thanks for the advice, I understand what you're saying although I still
haven't succeeded in getting the bitmap data from the memory map and back
into a TImage.

I just get an 'Invalid Bitmap Image' exception error when I try e.g:
Image2.Picture.LoadFromStream(memstream);

I'm also a bit confused as to why you suggest I should use
CreateFileMapping
to read back the stream, wouldn't OpenFileMapping be right for that?

TIA

Kim


"Joris" <XXXX@XXXXX.COM>writes
news:XXXX@XXXXX.COM...
>"kim" <XXXX@XXXXX.COM>writes
>news:3f57d601$XXXX@XXXXX.COM...
>>Does anyone know of an example of sharing DIBs using memory mapped
files?
>
>The exact same code, executed a second time, in whatever (other)
process,
>before you close the hMap in the original creating process, will serve
you.
>That is because the second CreateFileMapping call, given the same Name
>'MMBMP', will return a handle to the exact same file mapping, as long as
it
>does already exist (as well as *still* exist, hence the need to keep at
>least one reference to the memory mapped file alive by not executing the
>final CloseHandle statement in the creating process untill after you're
>confident the memory mapped file can be cleaned up).
>
>The fact that this Name parameter identifies the memory mapped file
accross
>processes, is a good reason to choose a more elaborate unique-ish name.
>Especially do not pick a name right from an example that you found on
the
>net. Chances are that you code will eventually run on a machine where
this
>name already has a meaning, probably because someone else found that
example
>too. It is custom to let the name start with the name of you company,
and
>continue with the name of the product, and next finalize with a
functional
>name part.
>
>>I
>>want to send a series of bitmaps from my Delphi application to my
Delphi
>>DLL.
>
>If this DLL is running in the context of your application, you already
share
>all memory, and there is no need to use memory mapped files. But you
already
>knew that, of course, sorry to point out the obvious.
>
>
>Joris
>
>


 

Re:sharing memory mapped bitmaps

Hey that fixed it, something simple as usual, and I can see why as well.
Thanks
kim
"Nils Haeck" <XXXX@XXXXX.COM>writes
Quote
To me, this sounds like the trap so many of us fall in:

Add
memstream.position := 0;

right before
Image2.Picture.LoadFromStream(memstream);

Hope that helps

Nils Haeck
www.simdesign.nl