Einzelnen Beitrag anzeigen

snook

Registriert seit: 25. Jun 2010
94 Beiträge
 
Delphi 2005 Professional
 
#6

AW: interface und variable des implementierenden objekts

  Alt 17. Dez 2011, 02:22
Nee ich gebe die referenzen nur ordnungsgemäß via := nil frei, und das objekt dahinter wird gar nicht in einer referenz gespeichert. benutze tatsächlich blos die reinen interfaces. Was hat es mit IUnknown und COM denn auf sich? in der deklaration ist doch IUnknown = IInterface definiert (system.pas)

zu dem thema DLL's, ich hatte jetzt in den letzten tagen mal etwas zeit um das zu untersuchen, war aber leider nciht mehr hier im forum. habe den fehler etwas eindämmen können:

Delphi-Quellcode:
IEnumerator = interface(IINterface)
  procedure Reset; stdcall;
  procedure GetFirst(out obj); stdcall;
  function GetLast(out obj): integer; stdcall;
  function MoveNext: boolean; stdcall;
  function GetCurrent(out obj): integer; stdcall;
end;

IDataModule = interface(IEnumerator)
  ...
end;

IStreamModule = interface(IDataModule)
  procedure LoadFromStream(const AStream: IStream; Size: LongWord); stdcall;
  ...
end;

TResourceManager = class(TCustomPlugIn)
  procedure InitPlugIn(const PlugIn: IPlugIn);
end;

TSomePlugIn = class(TCustomPlugIn)
  FData: IDataModule;
  procedure ReadProperties(const Data: IDataModule);
end;

TResourceManager.InitPlugIn(const PlugIn: IPlugIn);
var temp : IStreamModule;
    tempData: IDataModule;
    Stream : IStream;
    StatStg : TStatStg;
    sSize : integer;
    chSize : Int64;
begin
  temp := TStreamDataModule.Create;
  Stream = TStreamAdapter.Create(TFileStream.Create(PlugIn.ResourceFile, fmReadOnly), soOwned);
  try
    ...
    Stream.Seek(0, soFromBeginning, ChSize);
    Stream.Stat(stStat, sSize);
    temp.LoadFromStream(Stream, stStat.cbSize);
    PlugIn.ReadProperties(temp); // --> hier ignoriert er teilweise änderungen
    if temp.QueryInterface(IDataModule, tempData) = S_Ok then
      PlugIn.ReadProperties(tempData); // --> damit klappt es besser, gelegentlich aber auch nicht
  finally
    tempData := nil;
    Stream := nil;
    temp := nil;
  end;
end;
Das PlugIn kommt jetzt aus irgendeiner DLL, meldet sich beim Server an und der initialisiert dann das PlugIn über den ResourcenManager.

Damit das PlugIn seine Resourcen aus dem Datenmodul lesen kann, muss es durch die enthaltenen Daten durchmanövrieren, dazu hat das Datenmodul ein Enumerator-Interface. Im Reset wird dann ein Zähler des Datenmoduls auf -1 gesetzt und mit MoveNext erhöht. Nach dem Lesen der Daten aus dem Stream, hat der Zähler jedoch den Wert der Anzahl an Items im Module, also muss das PlugIn vor dem Lesebeginn diesen resetten, klar. Das klappt aber dann nicht mehr zuverlässig, kurioserweise hilft dann im extremfall, ein neustart

Geändert von snook (17. Dez 2011 um 02:46 Uhr)
  Mit Zitat antworten Zitat