[Erledigt] Interfaces und Instanzfreigabe

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut

[Erledigt] Interfaces und Instanzfreigabe

Beitragvon compmgmt » 29. Jan 2019, 21:28 [Erledigt] Interfaces und Instanzfreigabe

Hallo zusammen,

Bisher habe ich noch nicht sonderlich viel mit Interfaces gemacht, eigentlich fast nur abstrakte Klassen, wenn ich eine gleichwertige Funktionalität benötigt habe.

Ich habe eine Instanz einer Klasse, welche von einem Interface erbt. Diese wird irgendwann mal erstellt und irgendwann freigegeben. Nun habe ich folgendes Problem: Folgendes funktioniert nicht:
Code: Alles auswählen
const
  STest = '{982DE917-23B3-4FEF-B427-54E82D7866D5}';
 
type
  ITest = interface(IUnknown)
    [STest]
    procedure Test; stdcall;
  end;
 
  TTest = class(TInterfacedObject, ITest)
    public
      procedure Test; stdcall; virtual;
  end;
 
...
 
procedure TTest.Test; stdcall;
begin
  WriteLn('Test method called');
end;
 
var
  C: TTest; // Class instance
  I: ITest; // Interface instance. Diese wird irgendwann mal vom Nutzer angefordert.
 
begin
  C := TTest.Create;
  if C.GetInterface(STest, I) then begin
    I.Test;
  end
  else WriteLn('Error');
  ReadLn;
  C.Free; // Hier krachts
  ReadLn;
end.

Der Zeitpunkt des erhalten des Interfaces ist in meinem Fall nicht direkt bestimmbar, ebenso wenig der Zeitpunkt des Freigebens, zumal ich das ganze später aus einer DLL exportieren möchte. Die Instanz kann allerdings schon vorher existieren und anschließend auch weiter verwendet werden. Testweise mache ich das aber erstmal ohne DLL.

Es kracht mit RunError 204, was laut https://www.freepascal.org/docs-html/user/userap4.html folgendes ist:
https://www.freepascal.org/docs-html/user/userap4.html hat geschrieben: 204 Invalid pointer operation
You will get this in several cases:
• if you call Dispose or Freemem with an invalid pointer
• ...


Wieso ist das so und was kann ich da machen?
Zuletzt geändert von compmgmt am 29. Jan 2019, 22:30, insgesamt 1-mal geändert.
Code: Alles auswählen
InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)
compmgmt
 
Beiträge: 351
Registriert: 25. Nov 2015, 17:06
Wohnort: in der Nähe von Stuttgart
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4 | 
CPU-Target: i386 + x86_64
Nach oben

Beitragvon m.fuchs » 29. Jan 2019, 22:01 Re: Interfaces und Instanzfreigabe

Füge folgendes in deinen Programm-/Unitkopf ein:
Code: Alles auswählen
{$INTERFACES Corba}  


Und schmeißt die Ableitung von IUnknown raus.

Andernfalls ist das Interface referenzgezählt und führt ein automagisches .Free durch.
Und danach bitte die Entwicklungsabteilung bei Borland dafür verfluchen, dass sie so einen Schwachsinn eingeführt haben.

BTW: Ich glaube die GUID kannst du dann auch weglassen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
m.fuchs
Lazarusforum e. V.
 
Beiträge: 2067
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (Lazarus 2.0, FPC 3.0.4) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon compmgmt » 29. Jan 2019, 22:12 Re: Interfaces und Instanzfreigabe

Danke, funktioniert. Die GUID benötige ich aber für C.GetInterface(). Außerdem wird diese (glaube ich) für die Identifikation benötigt, wenn ich das Interface über eine DLL bzw ein SharedObject exportiere.

Edit: IUnknown hat sich aber scheinbar Microsoft ausgedacht (https://docs.microsoft.com/en-us/windows/desktop/api/unknwn/nn-unknwn-iunknown) und die können wohl auch nicht schreiben. Anders kann ich mir jedenfalls nicht erklären wo das "o" in "Unknwn.h" ist.
Code: Alles auswählen
InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)
compmgmt
 
Beiträge: 351
Registriert: 25. Nov 2015, 17:06
Wohnort: in der Nähe von Stuttgart
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4 | 
CPU-Target: i386 + x86_64
Nach oben

• Themenende •

Zurück zu Freepascal



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste

cron
porpoises-institution
accuracy-worried