Pregunta

Esta interfaz al archivo _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;

Esto mira sistema 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);
};

Función en apariencia como servidor COM

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

En i`m COM del cliente llamar a esta función como

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

y obtener el error excepción de primera oportunidad en $ 75A9FBAE. EAccessViolation clase de excepción con 'violación de acceso en la dirección 75A409A4 en el módulo 'mensaje Rpcrt4.dll'. Leer de dirección FFFFFFF8' . Proceso Project1.exe (2296)

Si quiero volver entero, `s funciona. Cómo devolver WideString?

¿Fue útil?

Solución

La forma correcta de manejar esta situación es como sigue:

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

Lo que a continuación se puede simplificar un poco utilizando el convenio de llamada safecall de Delphi en la declaración de Delphi (no en el mismo TypeLibrary) de la interfaz:

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

Otros consejos

No utilice los valores de retorno distintos de HRESULT. En su lugar poner su valor de retorno en la lista de parámetros como parámetro de salida.

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

De este modo, también está obligado a usar COM administrador de memoria IMalloc (CoTaskMemAlloc para pur COM, SysAllocString para la automatización).

Vamos a Delphi realizar las conversiones de forma automática. No eche. Puede convertir una cadena (ANSI) a un PChar, debido a que su diseño de memoria son compatibles, pero no se puede convertir una cadena a un widestring o viceversa. Delphi perfrom conversión cuando uno asignar a la otra.

En Delphi <2009

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

Es necesario utilizar SysAllocString() o SysAllocStringLen() para asignar el BSTR

excepción de primera oportunidad en $ 75A9FBAE. EAccessViolation clase de excepción con el mensaje 'Acceso violación en la dirección 75A409A4 en el módulo 'Rpcrt4.dll'

  1. el error está viniendo de Rpcrt4.dll

  2. EAccessViolation es causada principalmente por el acceso a un objeto nulo, paso a través de su código de asegurarse de que todos los objetos son objetos válidos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top