Frage

Diese Schnittstelle bei _TLB.pas Datei

// *********************************************************************//
// Interface: ITMyCOM
// Flags: (256) OleAutomation
// GUID: {D94769D0-F4AF-41E9-9111-4D8BC2F42D69}
// *********************************************************************//
ITMyCOM = interface(IUnknown)
['{D94769D0-F4AF-41E9-9111-4D8BC2F42D69}']
function MyDrawWS(a: Integer; b: Integer): WideString; stdcall;
end;

Das sieht bei Betriebssystem Windows

[
odl,
uuid(D94769D0-F4AF-41E9-9111-4D8BC2F42D69),
version(1.0),
helpstring("Interface for TMyCOM Object"),
oleautomation
]
interface ITMyCOM : IUnknown {
BSTR _stdcall MyDrawWS(
[in] long a, 
[in] long b);
};

Funktion in COM-Server aussieht wie

function TTMyCOM.MyDrawWS(a, b: Integer): WideString;
begin
Result := WideString(IntToStr(a+b));
end;

In COM-Client i`m Aufruf dieser Funktion wie

Edit1.Text := String(MyCOM.MyDrawWS(1,1));

und erhalten Fehler Erste Chance Ausnahme bei $ 75A9FBAE. Ausnahmeklasse EAccessViolation mit der Meldung ‚Zugriffsverletzung bei Adresse 75A409A4 in Modul‚RPCRT4.dll‘. Lesen der Adresse FFFFFFF8' . Prozess Projekt1.exe (2296)

Wenn ich Integer will zurückkehren, es `s funktioniert. Wie zurückzukehren Wide?

War es hilfreich?

Lösung

Der richtige Weg, dies zu handhaben ist wie folgt:

[ 
odl, 
uuid(D94769D0-F4AF-41E9-9111-4D8BC2F42D69), 
version(1.0), 
helpstring("Interface for TMyCOM Object"), 
oleautomation 
] 
interface ITMyCOM : IUnknown { 
HRESULT _stdcall MyDrawWS( 
[in] long a,  
[in] long b,
[out, retval] BSTR* ret); 
}; 

ITMyCOM = interface(IUnknown) 
  ['{D94769D0-F4AF-41E9-9111-4D8BC2F42D69}'] 
  function MyDrawWS(a: Integer; b: Integer; out ret: WideString): HResult; stdcall; 
end; 

function TTMyCOM.MyDrawWS(a, b: Integer; out ret: WideString): HRESULT; 
begin 
  ret := IntToStr(a+b);
  Result := S_OK;
end; 

var
  W: WideString;
begin
  OleCheck(MyCOM.MyDrawWS(1, 1, W));
  Edit1.Text := W;
end;

Was dann ein wenig vereinfacht werden kann durch die Verwendung von Delphi safecall Aufrufkonvention in der Delphi-Deklaration (in der Typbibliothek selbst) der Schnittstelle:

ITMyCOM = interface(IUnknown) 
  ['{D94769D0-F4AF-41E9-9111-4D8BC2F42D69}'] 
  function MyDrawWS(a: Integer; b: Integer): WideString; safecall;
end; 

function TTMyCOM.MyDrawWS(a, b: Integer): WideString;
begin 
  Result := IntToStr(a+b);
end; 

Edit1.Text := MyCOM.MyDrawWS(1, 1);

Andere Tipps

Verwenden Sie Rückgabewerte nicht anders als HRESULT. setzen Sie Ihren Rückgabewert stattdessen in Parameterliste als Ausgangsparameter.

function MyDrawWS(a: Integer; b: Integer; out str : WideString): HRESULT; stdcall;

Auf diese Weise sind Sie auch zu verwenden COM-Speichermanager IMalloc (CoTaskMemAlloc für pur COM, SysAllocString für Automation) gezwungen.

Let Delphi führen Sie die Konvertierungen automatisch. Nicht werfen. Sie können eine (ANSI) Zeichenfolge in einen PChar umwandeln, weil ihr Gedächtnis Layout kompatibel sind, aber Sie können einen String in einem Wide oder umgekehrt nicht gegossen. Delphi wird perfrom Umwandlung, wenn Sie assign einem zum anderen.

In Delphi <2009

var
S: string;
W: WideString;
...
S := W;  // Conversion, WideString -> AnsiString;
W := S; // Conversion, AnsiString -> WideString

Sie müssen verwenden SysAllocString() oder SysAllocStringLen() die BSTR zuweisen

Erste Chance Ausnahme bei $ 75A9FBAE. Ausnahmeklasse EAccessViolation mit der Meldung ‚Zugriffsverletzung bei Adresse 75A409A4 in Modul‚RPCRT4.dll‘

  1. der Fehler von RPCRT4.dll kommt

  2. EAccessViolation wird hauptsächlich verursacht durch ein Null-Objekt zugreifen, Schritt für Schritt durch den Code stellen Sie sicher, alle Objekte sind gültige Objekte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top