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/)
-   -   Speicher Freigabe? (https://www.delphipraxis.net/153780-speicher-freigabe.html)

msickel 16. Aug 2010 08:41

Speicher Freigabe?
 
Hallo,

Ich habe mal eine Frage.

Ich habe bei untem stehenden Code die MWI Scripting eingebunden (WBEMSCRIPTING_TLB)
Wenn ich nun auf eine Form einen Button lege und diesen Code einfüge wird bei jedem Knopfdruck Speicher verbraucht, beende ich das Programm wird der Speicher wieder frei gegeben. Wie kann ich den Speicher jedoch zur Laufzeit weider freigeben ohne das Programm beenden zu müssen.

Delphi-Quellcode:
var
  Locator : ISWbemLocator;
begin

  Locator := CoSWbemLocator.Create;

end;
Ein Locator.Free gibt es nicht und den Locator mit nil zu inizialisieren bringt auch nichts. Wie geht es richtig?

Martin

youuu 16. Aug 2010 08:57

AW: Speicher Freigabe?
 
Ich kenn mich mit MWI Scripting nicht aus, aber "FreeAndNil(Locater);" schon getestet?

Edit: Oh Berhard weiß es wohl besser

Bernhard Geyer 16. Aug 2010 08:57

AW: Speicher Freigabe?
 
Du machst das schon richtig bzw. bei Delphi-Interaces braucht man eigentlich fast nix beachten.

Fall wirklich Speicher verloren geht so liegt ein Fehler in der Implemenierung auf MS-Seite vor und du kannst eigentlich nix mache außer nicht permantent neue Interfaces Anforderung sondern diese zu cachen.

himitsu 16. Aug 2010 09:06

AW: Speicher Freigabe?
 
Ist das denn der ganze Code?

ich hab bei einigen WMI-Codes Problemchen mit einem Interface/Variant über einen OUT-Parameter mitbekommen, wo das Alte nicht freigegeben wird.

Dann muß man das Result (einen Variant) auch noch selber freigeben, da dieses nicht automatisch geschieht usw.


Aber theoretisch reicht es, wenn man ein Interface per :=nil freigibt (Delphi macht dieses z.B. beim Entfernen einer lokalen Variable automatisch).

msickel 16. Aug 2010 09:20

AW: Speicher Freigabe?
 
Das habe ich getestet, gibt einen Error :-)

Martin

Zitat:

Zitat von youuu (Beitrag 1042472)
Ich kenn mich mit MWI Scripting nicht aus, aber "FreeAndNil(Locater);" schon getestet?

Edit: Oh Berhard weiß es wohl besser


msickel 16. Aug 2010 09:21

AW: Speicher Freigabe?
 
Kannst Du mir für das "cachen" ein Beispiel geben?

Martin

Zitat:

Zitat von Bernhard Geyer (Beitrag 1042471)
Du machst das schon richtig bzw. bei Delphi-Interaces braucht man eigentlich fast nix beachten.

Fall wirklich Speicher verloren geht so liegt ein Fehler in der Implemenierung auf MS-Seite vor und du kannst eigentlich nix mache außer nicht permantent neue Interfaces Anforderung sondern diese zu cachen.


Bernhard Geyer 16. Aug 2010 09:52

AW: Speicher Freigabe?
 
Zitat:

Zitat von msickel (Beitrag 1042478)
Kannst Du mir für das "cachen" ein Beispiel geben?

Einfach hier das Singleton-pattern anwenden


Delphi-Quellcode:
function GetLocator: ISWbemLocator;

implementation

var
  FLocal: ISWbemLocator;

function GetLocator: ISWbemLocator;
begin
  if not Assigned(FLocal) then
    FLocal := CoSWbemLocator.Create;

  result := FLocal;
end;

msickel 16. Aug 2010 10:23

AW: Speicher Freigabe?
 
Ah..... :-)

Vielen Dank

Zitat:

Zitat von Bernhard Geyer (Beitrag 1042486)
Zitat:

Zitat von msickel (Beitrag 1042478)
Kannst Du mir für das "cachen" ein Beispiel geben?

Einfach hier das Singleton-pattern anwenden


Delphi-Quellcode:
function GetLocator: ISWbemLocator;

implementation

var
  FLocal: ISWbemLocator;

function GetLocator: ISWbemLocator;
begin
  if not Assigned(FLocal) then
    FLocal := CoSWbemLocator.Create;

  result := FLocal;
end;


msickel 17. Aug 2010 20:03

AW: Speicher Freigabe?
 
Hi, leider komme ich nicht wirklich weiter, ich habe folgenden Code der aber bei jedem Druck auf den Button Speicher frisst, was mache ich falsch?

Bin für jede Hilfe dankbar

Delphi-Quellcode:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, activex, comobj, ExtCtrls,
  ShellAPI, ExceptionLog;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
   
  private
    { Private declarations }
  public
    { Public declarations }
   
  end;

var
  Form1: TForm1;

implementation


{$R *.dfm}


uses
  WbemScripting_TLB;


var
  aLoc : ISWbemLocator;
  aSrv : ISWbemServices;
  aObjSet : ISWbemObjectSet;
  pEnum : IEnumVARIANT;
  vOut : OleVariant;
  dwRetrieved : LongWord;
  hRes : HResult;
  sNetConnectionID, sNetConnectionStatus : String;
  iNetConnectionStatus : Integer;

function GetLocator : ISWbemLocator;
begin
  if not Assigned(aLoc) then
     aLoc := CoSWbemLocator.Create;

  result := aLoc;
end;

function GetServices : ISWbemServices;
begin
  if not Assigned(aSrv) then
     aSrv := aLoc.ConnectServer ('','root\cimv2', '','','','',0, nil);

  result := aSrv;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin

  Listbox1.Items.Clear;

  aLoc := GetLocator;
  aSrv := GetServices;

  aObjSet := aSrv.ExecQuery ('SELECT NetConnectionID, NetConnectionStatus FROM Win32_NetworkAdapter', 'WQL', 0, nil);

  pEnum := aObjSet.Get__NewEnum as IEnumVARIANT;

  while (true) do
  begin
    hRes := pEnum.Next (1, vOut, dwRetrieved);
    if not (hRes = S_OK) then
      Break;

    if (VarIsNull(vOut.NetConnectionID)) then
      Continue;

    sNetConnectionID := vOut.NetConnectionID;
    iNetConnectionStatus := vOut.NetConnectionStatus;
    if iNetConnectionStatus = 2 then
      sNetConnectionStatus := 'verbunden';
    if iNetConnectionStatus = 7 then
      sNetConnectionStatus := 'nicht verbunden';

    ListBox1.Items.Add(sNetConnectionID + ' = ' + sNetConnectionStatus);

  end;

//  VarClear(vOut);
//  hRes := 0;
//  pEnum := nil;
//  aLoc := nil;
//  aSrv := nil;
//  aObjSet := nil;

end;

end.
Martin

GHorn 18. Aug 2010 07:28

AW: Speicher Freigabe?
 
Moin,

aLoc und aSrv sind globale Variablen. Es würde
also ein einfacher Aufruf der Funktionen "GetLocator" und "GetServices" reichen.

Alle Variablen, die danach gesetzt werden (aObjSet, pEnum, hRes usw.), können bzw. sollten lokal deklariert werden - es sei denn sie werden irgendwo im Code noch gebraucht. Dadurch werden sie am Ende der Buttonclick-Funktion von Delphi sauber abgeräumt.

Die Zeile

Delphi-Quellcode:
    if (VarIsNull(vOut.NetConnectionID)) then
      Continue;
erschließt sich mir nicht. Wenn da False rauskommt, würde die while-Schleife trotzdem fortgesetzt.

Besser wäre m.E.:

Delphi-Quellcode:
var
bContinue: Boolean;
...
begin
  bContinue := True;
  while bContinue do
    begin
      ....
      if (not (hRes = S_OK)) or
         ((VarIsNull(vOut.NetConnectionID))) then
        bContinue := False;
      if bContinue then
        begin
          sNetConnectionID := vOut.NetConnectionID;
          ....
        end;
    end;
Gruß
Gerald


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:14 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