AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Speicherreservierung / Verständnisfrage
Thema durchsuchen
Ansicht
Themen-Optionen

Speicherreservierung / Verständnisfrage

Ein Thema von x000x · begonnen am 21. Aug 2005 · letzter Beitrag vom 23. Aug 2005
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von x000x
x000x

Registriert seit: 21. Jan 2004
Ort: Bei Hamburg
308 Beiträge
 
Delphi XE2 Professional
 
#1

Speicherreservierung / Verständnisfrage

  Alt 21. Aug 2005, 23:43
Moin moin,

ich habe vor einiger Zeit hier im Forum diesen Thread gefunden.
Habe mir anhand der Informationen eine funktion gebastelt, die mir ein Jpeg aus einer Resource lädt.
Delphi-Quellcode:
function LoadPictureFromRes(Instance: THandle; const szResName, szResType : String; var pPicture: IPicture) : Boolean;
const IID_IPicture : TGUID = '{7BF80980-BF32-101A-8BBB-00AA00300CAB}';
var
   hResInfo,
   hResGlobal : THandle;
   dwResSize : DWord;
   pResData : Pointer;
   //
   hMem : THandle;
   pData : Pointer;
   //
   hRslt : HResult;
   pStream : IStream;
Begin
   Result := False;
   hResInfo := FindResource(Instance, Pointer(szResName), Pointer(szResType));
   if hResInfo = 0 then
      Exit;
   hResGlobal := LoadResource(Instance, hResInfo);
   if hResGlobal = 0 then
      Exit;
   hMem := 0;
   try
      pResData := LockResource(hResGlobal);
      if Not Assigned(pResData) then
        Exit;

      dwResSize := SizeofResource(Instance, hResInfo);
      if dwResSize = 0 then
         Exit;

      hMem := GlobalAlloc(GHND or GMEM_NODISCARD, dwResSize);
      if hMem = 0 then
         Exit;

      pData := GlobalLock(hMem);
      if Not Assigned(pData) then
         Exit;

      Move(pResData^, pData^, dwResSize);
      GlobalUnlock(hMem);

      pStream := nil;
      hRslt := CreateStreamOnHGlobal(hMem, True, pStream);
      if FAILED(hRslt) or (pStream = nil) then
         Exit;

      hRslt := OleLoadPicture(pStream, dwResSize, False, IID_IPicture, pPicture);
      if (hRslt = S_OK) and (pPicture <> nil) then
         Result := True;
   finally
      pStream := nil;
      if hMem <> 0 then
         GlobalFree(hMem);
      if hResGlobal <> 0 then
         FreeResource(hResGlobal);
   end;
end;
Sie funktioniert, nur habe ich dabei ein Verständnis Problem:
Ich lade das Image aus der Resource mit MSDN-Library durchsuchenLoadResource welche mir ein Handle
auf einen Speicherbereich liefert (HGLOBAL).
Die Funktion MSDN-Library durchsuchenCreateStreamOnHGlobal erwartet als ersten Parameter ebenfalls
ein Handle auf einen Speicherbereich vom Type HGlobal.
Warum muss ich den Zwischenschritt mit MSDN-Library durchsuchenGlobalAlloc und Move machen damit ich
letztendlich an die Daten komme?

Davon mal abgesehen, würde ich gerne auf GlobalAlloc verzichten. Mein Win32API Buch (http://www.amazon.de/exec/obidos/ASIN/3932311051/delphipraxis-21)
sagt mir, dass GlobalAlloc und Konsorten Relikte aus der Win16 Zeit sind und intern auf die Virtual-Funktionen
abgebildet werden.
Jeder Versuch die Virtual* -Funktionen hiermit (CreateStreamOnHGlobal) zu nutzen, schlug fehl.

Was genau ist denn bei den Virtual* funktionen anders und warum funktioniert CreateStreamOnHGlobal nur mit
GlobalAlloc?
Wäre vieleicht mal jemand so lieb/nett und könnte mir das mal erklären?
*liebgrins*
Peter
-= Gruss Peter =-
-= alias x000x =-
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Speicherreservierung / Verständnisfrage

  Alt 22. Aug 2005, 00:06
Wie alt ist das Buch? Im aktuellen PSDK stzeht nichts davon, dass diese Funktion veraltet wäre. Da steht nur:
Zitat:
Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions.
aber nichts von veraltet.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#3

Re: Speicherreservierung / Verständnisfrage

  Alt 22. Aug 2005, 00:41
Zitat von Luckie:
Wie alt ist das Buch?
7 Jahre. Erste Auflage 1998, 2te 1999 und 3te 2000. Ich habe die 3te hier vor mir.

Zitat von Luckie:
Im aktuellen PSDK stzeht nichts davon,
Ich würde doch auch dringend das PSDK anraten!
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#4

Re: Speicherreservierung / Verständnisfrage

  Alt 22. Aug 2005, 00:45
Code kopiert und nicht verstanden? ... das rot markiert müßtest du komplett weglassen können. Das diente im Ursprungscode ja nur dem Kopieren der Daten aus der Datei in einen allozierten Speicherbereich. Da du aber bereits ein Handle hast, kannst du dir das sparen.
Code:
function LoadPictureFromRes(Instance: THandle; const szResName, szResType : String; var pPicture: IPicture) : Boolean;
const IID_IPicture : TGUID = '{7BF80980-BF32-101A-8BBB-00AA00300CAB}';
var
   hResInfo,
   hResGlobal : THandle;
   dwResSize  : DWord;
   pResData   : Pointer;
   //
   hMem       : THandle;
   pData      : Pointer;
   //
   hRslt      : HResult;
   pStream    : IStream;
Begin
   Result  := False;
   hResInfo := FindResource(Instance, Pointer(szResName), Pointer(szResType));
   if hResInfo = 0 then
      Exit;
   hResGlobal := LoadResource(Instance, hResInfo);
   if hResGlobal = 0 then
      Exit;
   hMem  := 0;
   try
[color=red]     pResData := LockResource(hResGlobal);
      if Not Assigned(pResData) then
        Exit;

      dwResSize := SizeofResource(Instance, hResInfo);
      if dwResSize = 0 then
         Exit;

      hMem := GlobalAlloc(GHND or GMEM_NODISCARD, dwResSize);
      if hMem = 0 then
         Exit;

      pData := GlobalLock(hMem);
      if Not Assigned(pData) then
         Exit;

      Move(pResData^, pData^, dwResSize);
      GlobalUnlock(hMem);[/color]

      pStream := nil;
      hRslt  := CreateStreamOnHGlobal(hMem, True, pStream);
      if FAILED(hRslt) or (pStream = nil) then
         Exit;

      hRslt := OleLoadPicture(pStream, dwResSize, False, IID_IPicture, pPicture);
      if (hRslt = S_OK) and (pPicture <> nil) then
         Result := True;
   finally
      pStream := nil;
      if hMem <> 0 then
         GlobalFree(hMem);
      if hResGlobal <> 0 then
         FreeResource(hResGlobal);
   end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von x000x
x000x

Registriert seit: 21. Jan 2004
Ort: Bei Hamburg
308 Beiträge
 
Delphi XE2 Professional
 
#5

Re: Speicherreservierung / Verständnisfrage

  Alt 22. Aug 2005, 21:56
Moin moin,
Zitat von Olli:
Code kopiert und nicht verstanden? ... das rot markiert müßtest du komplett weglassen können. Das diente im Ursprungscode ja nur dem Kopieren der Daten aus der Datei in einen allozierten Speicherbereich. Da du aber bereits ein Handle hast, kannst du dir das sparen.
Zitat von x000x:
... welche mir ein Handle auf einen Speicherbereich liefert (HGLOBAL).
... erwartet als ersten Parameter ebenfalls ein Handle auf einen Speicherbereich vom Type HGlobal.
... Warum muss ich den Zwischenschritt mit GlobalAlloc und Move machen damit ich
letztendlich an die Daten komme?
@Olli: Standard Satz geschrieben und meinen 1. Beitrag nicht gelesen?

Jetzt aber mal im ernst, genau das habe ich mir auch so gedacht und mich gewundert warum es
denn nicht funktioniert. Und dafür wollte ich eine Erklärung haben, da ich genau Das nicht verstehe.
Sorry, falls ich mich missverständlich ausgedrückt habe

@Luckie: Ich habe die 1. Auflage von diesem Buch und werde in Zukunft das PSDK befragen...

[Edit] Hatte Luckie falsch geschrieben [/Edit]
Peter
-= Gruss Peter =-
-= alias x000x =-
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Speicherreservierung / Verständnisfrage

  Alt 22. Aug 2005, 22:05
Zitat von x000x:
[Edit] Hatte Luckie falsch geschrieben [/Edit]
Es sei dir noch einmal verziehen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#7

Re: Speicherreservierung / Verständnisfrage

  Alt 22. Aug 2005, 23:06
Zitat von x000x:
@Olli: Standard Satz geschrieben und meinen 1. Beitrag nicht gelesen?
Gelesen schon, aber dann wohl mißverstanden. Könntest du bitte mal ein kleines Projekt posten, damit ich mir nicht alles zusammensuchen muß. Dann würde ich es mir mal schnell in Aktion anschauen. Danke.

Zitat von x000x:
Jetzt aber mal im ernst, genau das habe ich mir auch so gedacht und mich gewundert warum es
denn nicht funktioniert. Und dafür wollte ich eine Erklärung haben, da ich genau Das nicht verstehe.
Es kann dann eigentlich nur noch mit den Speicherseiten zu tun haben. Vermutlich hat man auf das Handle nicht vollen Zugriff, was aber zB für die unten aufgerufene Funktion benötigt wird.
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#8

Re: Speicherreservierung / Verständnisfrage

  Alt 22. Aug 2005, 23:13
So, vergiß das Gesagte. Wäre ich nicht zu faul gewesen mal ins PSDK zu schauen, hätte ich die Lösung sofort gesehen. Das Handle welches MSDN-Library durchsuchenFindResource() zurückliefert ist nicht vom Typ HGLOBAL! Stattdessen ist es HRSRC. Unter Delphi ist das nicht wichtig, C oder C++ hätten vermutlich (?) gemeckert. Jedenfalls ist es kein HGLOBAL und somit auch kein Handle im Sinne von MSDN-Library durchsuchenGlobalAlloc().

Damit wäre das Rätsel gelöst. Die Daten müssen also mindestens einmal kopiert werden.

Nachtrag:
... und wenn ich jetzt noch bei allen beiteiligten Funktionen nachgeguckt hätte, wäre mir folgendes aufgefallen
Dokumentation von LockResource() im PSDK 2003:
hResData
[in] Handle to the resource to be locked. The LoadResource function returns this handle. Note that this parameter is listed as an HGLOBAL variable only for backwards compatibility. Do not pass any value as a parameter other than a successful return value from the LoadResource function.
  Mit Zitat antworten Zitat
Benutzerbild von x000x
x000x

Registriert seit: 21. Jan 2004
Ort: Bei Hamburg
308 Beiträge
 
Delphi XE2 Professional
 
#9

Re: Speicherreservierung / Verständnisfrage

  Alt 23. Aug 2005, 01:15
Moin moin,

Zitat von Olli:
Das Handle welches FindResource () zurückliefert ist nicht vom Typ HGLOBAL!
Ok, wenn ich ehrlich bin, habe ich dich auch nicht so verstanden, dass ich allein mit FindResource auskomme.
Ich hatte eher daran gedacht, LoadResource zu verwenden, da hier ein HGLOBAL zurückgegeben wird. Das es allerdings
auch nicht wirklich ein Handle auf einen Globalen Speicherblock zurückliefert, habe ich auch erst eben nach
deinem Post gelesen

Nur was ist denn der eigentliche Unterschied? Wenn ich eine Resource in den Speicher lade, befindet sich diese
doch auch "nur im Speicher"?!

Und warum kann ich nicht mit den Virtual** funktionen auf diesen Speicher zugreifen?
Diese funktionen sind doch auch nur für "Speicher-" zugriffe etc. da?!
Es wäre schön, wenn Ihr mir ein paar Links empfehlen könntet, wo ich derartiges
(Unterschiede Virtueller-/Globaler-/loakaler-/Heap- Speicher) mal nachlesen kann...

So, ich habe jetzt dochmal ein Testprojekt zusammengestellt, falls es doch noch jemanden interessiert,
bzw. jemand Sourcen zum testen des oben angesprochenen braucht...

[OT]
Die verwendetet Buttonklasse ist noch nicht fertig und meine Erste ohne die VCL... Also wenn Ihr
hier eurer Meinung nach Sinnloses Zeug drin findet (findet Ihr bestimmt), dann lasst es mich doch bitte wissen...
(Was nicht heisst, dass ich hier bewusst "Sinnloses Zeugs" geschrieben habe)
(Ich möchte keine Codebeispiele haben, sondern dann nur sachlich begründete Aussagen)
[/OT]
Angehängte Dateien
Dateityp: zip restest_594.zip (45,9 KB, 21x aufgerufen)
Peter
-= Gruss Peter =-
-= alias x000x =-
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#10

Re: Speicherreservierung / Verständnisfrage

  Alt 23. Aug 2005, 01:25
HGLOBAL steht übrigens nur in älteren Doks. - in den neuen ist's HRSRC!

Zitat von x000x:
Nur was ist denn der eigentliche Unterschied? Wenn ich eine Resource in den Speicher lade, befindet sich diese doch auch "nur im Speicher"?!
Du lädst sie ja nicht, sondern ermittelst nur ein Handle bzw. ein Pointer auf die Ressource. In den meisten Fällen dürfte sie bereits vom PE-Loader mitgeladen worden sein - ansonsten wird sie nachgeladen. Allerdings ist dies dann in Form von MMFs.

Zitat von x000x:
Und warum kann ich nicht mit den Virtual** funktionen auf diesen Speicher zugreifen?
Diese funktionen sind doch auch nur für "Speicher-" zugriffe etc. da?!
Es wäre schön, wenn Ihr mir ein paar Links empfehlen könntet, wo ich derartiges
(Unterschiede Virtueller-/Globaler-/loakaler-/Heap- Speicher) mal nachlesen kann...
Hatten wir letztens mit Luckie: die Heapfunktionen erlauben den Zugriff auf einen beliebigen Heap (ja ein Prozeß kann mehrere davon haben. Die Virtualfunktionen erlauben das prinzipiell auch für andere Prozesse und die Local*/Global*-Funktionen sind eigentlich Überbleibsel aus Win16. Ich werde mir aber eben nochmal anschauen wie die im Disassembler aussehen und dir dann bescheidgeben. Kann aber auch sein, daß ich es dann erstmal beseitelege und später fortfahre. Notfalls mußt du mich per PN erinnern.

Zitat von x000x:
Die verwendetet Buttonklasse ist noch nicht fertig und meine Erste ohne die VCL... Also wenn Ihr hier eurer Meinung nach Sinnloses Zeug drin findet (findet Ihr bestimmt), dann lasst es mich doch bitte wissen...
Ich werde auch eine schreiben und ebenfalls eine Hyperlink-Klasse. Aber zuerst mache ich das alles in C und danach dann nochmal in Delphi

Zitat von x000x:
(Ich möchte keine Codebeispiele haben, sondern dann nur sachlich begründete Aussagen)
Waren unsere Aussagen bisher so schlimm?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:23 Uhr.
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