Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi TBitmap von zwei Programmen austauschen (Speicher zuweisen) (https://www.delphipraxis.net/110296-tbitmap-von-zwei-programmen-austauschen-speicher-zuweisen.html)

Cyberstorm 16. Mär 2008 11:28


TBitmap von zwei Programmen austauschen (Speicher zuweisen)
 
Hallo.

Ich möchte ein Speicherresistentes TBitmap von einem Programm in einem anderen verwenden.
Ich hoffe doch, dass dies irgendwie möglich ist?!

Im Endeffekt möchte ich dem "neuen" TBitmap den selben Speicher zuweisen wie dem "originalem" also

bmp1:=bmp2;

aber halt programmübergreifend.


ps: wie ich Daten (z.b. eine Speicheradresse) zwischen den Programmen austauschen kann weiß ich.


Vielen Dank für Hilfe!

Muetze1 16. Mär 2008 12:19

Re: TBitmap von zwei Programmen austauschen (Speicher zuweis
 
Schreib lieber wozu du das brauchst, also was du eigentlich erreichen willst. So klappt dies nicht, da das Bitmap im jeweils anderen Adressraum liegt und auch die Klassen-Typen nicht gleich wären. Von daher erläutere mal lieber was du eigentlich willst. Wahrscheinlich musste über das Handle gehen.

Cyberstorm 16. Mär 2008 12:43

Re: TBitmap von zwei Programmen austauschen (Speicher zuweis
 
Programm A bekommt Bilder (TBitmap) von einer WebCam.
Programm B lässt eine Art Gesichtserkennung über eine dll drüber laufen.

Die dll exportiert eine Funktion, über die ein Bild per Bitmap Handle geladen wird:
"LoadImageFromHBitmap(BitmapHandle: HBitmap)"

Die dll ist nicht von mir und hat Speicherlecks + produziert nach einigen Aufrüfen hier und da frühlige Zugriffsverletzungen.
Da ein dynamischen einbinden (mit LoadLibrary, FreeLibrary) Probleme gemacht hat (FreeLibrary hing immer so ca. 5Sekunden) sah ich mich gezwungen den Teil mit der dll in eine kleine Konsolenanwendung auszulagern, die dann vom Hauptprogramm mit Parametern aufgerufen wird.

Da die ganze Geschichte relativ zeitkritisch ist, wollte ich mir die Zeit sparen, das Bitmap auf die Festplatte zu speichern und anschließend wieder zu laden, da ich es ja eh schon im Speicher habe.
Da es von der WebCam kommt ist es ja auch erstmal nicht auf der Platte...

Kann ich nicht das Bitmap über SaveToStream per MemoryStream oder so als MemoryMappedFile im Speicher sichern und dann in dem anderen Prog wieder laden?

Am liebsten wäre mir natürlich, wenn ich die Daten direkt über Assign oder so zuweisen könnte.

Cyberstorm 16. Mär 2008 16:17

Re: TBitmap von zwei Programmen austauschen (Speicher zuweis
 
Also ich habe es jetzt folgendermaßen leider erfolglos probiert ein Bitmap über ein Memory Mapped File auszutauschen.
Leider kommen in dem Stream nur Nullen an :-(
Findet jemand einen Fehler?


Sender:

Delphi-Quellcode:
const
 mmfName = 'FaceBitmapData';

procedure WriteToMMF(m: TMemoryStream; Filename: string);
var
  hFileMapping: THandle;
  Mem: Pointer;
begin
  hFileMapping:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, m.Size, PChar(Filename));
  if hFileMapping <> 0 then
    begin
      Mem:=MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, 0);
      if Assigned(Mem) then
        begin
          CopyMemory(Mem, m.Memory, m.Size);
          CloseHandle(hFileMapping);
        end;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  bmp: TBitmap;
  mStream: TMemoryStream;
begin
  bmp:=TBitmap.Create;
  mStream:=TMemoryStream.Create;
    try
      bmp.LoadFromFile('c:\t.bmp');
      bmp.SaveToStream(mStream);
      WriteToMMF(mStream, mmfName);
      ExecuteFile(ExtractFilePath(ParamStr(0)) + 'ReadKonsole.exe', mmfName + ' ' + IntToStr(mStream.Size), '', false, true);
    finally
      FreeAndNil(bmp);
      FreeAndNil(mStream);
    end;
end;

Empfänger (KonsolenApp):
Delphi-Quellcode:
var
  Bmp: TBitmap;
  OldRegVal: String;
  inSize: Integer;
  hFileMapping: THandle;
  Mem: Pointer;
  m: TMemoryStream;
begin
  Bmp:=TBitmap.Create;
  m:=TMemoryStream.Create;
    try
      inSize:=StrToInt(ParamStr(2));
      hFileMapping:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READONLY, 0, inSize, PChar(ParamStr(1)));
      if hFileMapping <> 0 then
        begin
          Mem:=MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
          if Assigned(Mem) then
            begin
              m.SetSize(inSize);
              m.Seek(0, soFromBeginning); //unnötig?!
              CopyMemory(m.Memory, Mem, inSize);
              m.SaveToFile('c:\stream.dat');
              Bmp.LoadFromStream(m);
              Bmp.SaveToFile('c:\out.bmp');
            end;
          CloseHandle(hFileMapping);
        end;
    finally
      FreeAndNil(Bmp);
      FreeAndNil(m);
    end;

Danke schonma!

Cyberstorm 16. Mär 2008 16:45

Re: TBitmap von zwei Programmen austauschen (Speicher zuweis
 
Argh hab meinen Fehler.

Ist schon schlau, wenn man das Handle wieder schließt, bevor man die daten ausliest...

"CloseHandle(hFileMapping);" muss beim sender natürlich raus...

Muetze1 16. Mär 2008 18:08

Re: TBitmap von zwei Programmen austauschen (Speicher zuweis
 
Aber mal was anderes: Wenn deine App TBitmap von der WebCAM bekommt und die DLL (die ja nun von der Console App angezogen wird) ein HBITMAP Handle haben will, dann verschicke doch einfach nur das? Diese 4 Bytes sind doch einfach zwischen den Prozessen verschickbar, da Windows die Bitmapdaten hat und das Handle eindeutig ist. Warum soviel Aufwand die Bilddaten auf den anderen Prozess zu schieben, wenn Windows diese doch hat und die DLL diese noch nicht mal will sondern die auch nur über das Handle von Windows holt?

Cyberstorm 16. Mär 2008 18:11

Re: TBitmap von zwei Programmen austauschen (Speicher zuweis
 
Das war natürlich mein erster Versuch.

Klappt aber nicht.
Gibt ne Zugriffsverletzung.
Ich denke mal, dass es daran liegt, dass das Handle auf den (geschützten) Speicherbereich des anderen Programms zeigt.

Muetze1 16. Mär 2008 18:20

Re: TBitmap von zwei Programmen austauschen (Speicher zuweis
 
Zitat:

Zitat von Cyberstorm
Das war natürlich mein erster Versuch.

Klappt aber nicht.
Gibt ne Zugriffsverletzung.
Ich denke mal, dass es daran liegt, dass das Handle auf den (geschützten) Speicherbereich des anderen Programms zeigt.

Das Handle ist nur eine eindeutige "Zahl" die von Windows vergeben wird beim anlegen des Bitmaps und einfach nur ein eindeutiges Objekt angibt. Es kann definitiv keine AV auslösen, wenn das Handle nicht gültig ist. Die AV muss an was anderem gelegen haben.

Cyberstorm 16. Mär 2008 18:28

Re: TBitmap von zwei Programmen austauschen (Speicher zuweis
 
Ja, aber die Zugriffsverletzung kommt, wenn die dll probiert Daten von dem Handle zu lesen und merkt, dass da nichts kommt ;-).

Probier es doch aus wenn du mir nicht glaubst:

Programm1: Bitmap Laden + Handle ausgeben (editfeld oder whatever);
Programm2: Bitmap erzeugen, Handel zuweisen, Bitmap speichern.

wird ein leeres Bitmap bei rauskommen.

bitsetter 16. Mär 2008 18:31

Re: TBitmap von zwei Programmen austauschen (Speicher zuweis
 
Kann ich bestätigen, hatte ich auch schon mal ausprobiert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:25 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz