Domanda

Questa interfaccia a file di _TLB.pas

// *********************************************************************//
// 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;

Questa guarda operativo 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);
};

Funzione nel look server COM come

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

`m In COM client di chiamare questa funzione come

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

e ottenere l'errore eccezione Prima possibilità a $ 75A9FBAE. Eccezione di classe EAccessViolation con 'Violazione di accesso all'indirizzo 75A409A4 nel modulo 'messaggio rpcrt4.dll'. Leggi di indirizzo FFFFFFF8' . Processo Progetto1.exe (2296)

Se voglio tornare Integer, `s funziona. Come restituire WideString?

È stato utile?

Soluzione

Il modo corretto per gestire questa situazione è la seguente:

[ 
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;

che possono poi essere semplificato un po 'utilizzando safecall convenzione di chiamata di Delphi nella dichiarazione Delphi (non nel TypeLibrary stesso) dell'interfaccia:

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);

Altri suggerimenti

Non utilizzare i valori restituiti diversi HRESULT. Invece mettere il valore di ritorno nella lista dei parametri come parametro di uscita.

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

In questo modo, si è costretti anche ad uso COM gestore di memoria IMalloc (CoTaskMemAlloc per PUR COM, SysAllocString per l'Automazione).

Let Delphi eseguire automaticamente le conversioni. Non pressofuso. Si può lanciare una stringa (ANSI) per un PChar, perché il loro layout di memoria sono compatibili, ma non è possibile lanciare una stringa in un WideString o viceversa. Delphi perfrom conversione quando un assegnare all'altro.

In Delphi <2009

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

È necessario utilizzare SysAllocString() o SysAllocStringLen() di destinare l'BSTR

Per prima eccezione di possibilità a $ 75A9FBAE. classe di eccezione EAccessViolation con il messaggio 'Violazione di accesso all'indirizzo 75A409A4 nel modulo 'rpcrt4.dll'

  1. l'errore viene da rpcrt4.dll

  2. EAccessViolation è in gran parte causato da l'accesso a un oggetto null, passo attraverso il codice di assicurarsi che tutti gli oggetti sono oggetti validi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top