Question

Cette interface au fichier _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;

Cela ressemble à OS de 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);
};

Fonction de serveur dans les regards COM comme

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

COM client i`m appeler cette fonction comme

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

et obtenir erreur Première exception de chance $ 75A9FBAE. Exception classe EAccessViolation avec le message « Violation d'accès à l'adresse 75A409A4 dans le module 'rpcrt4.dll'. Lire d'adresse FFFFFFF8. Procédé Project1.exe (2296)

Si je veux retourner entier, il s `fonctionne. Comment revenir WideString?

Était-ce utile?

La solution

La bonne façon de gérer est la suivante:

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

Ce qui peut alors être simplifié un peu en utilisant la convention d'appel Delphi safecall dans la déclaration Delphi (pas dans le TypeLibrary lui-même) de l'interface:

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

Autres conseils

Ne pas utiliser des valeurs de retour autres que HRESULT. Au lieu de mettre votre valeur de retour dans la liste des paramètres en tant que paramètre de sortie.

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

De cette façon, vous êtes également obligé d'utiliser le gestionnaire de mémoire COM IMalloc (CoTaskMemAlloc pour COM pur, SysAllocString Automation).

Soit Delphi effectuer les conversions automatiquement. Ne pas jeter. Vous pouvez lancer une chaîne (ansi) à un PChar, parce que leur mise en page de mémoire sont compatibles, mais vous ne pouvez pas lancer une chaîne à un WideString ou vice-versa. Delphi conversion perfrom lorsque vous attribuez un à l'autre.

Dans Delphi <2009

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

Vous devez utiliser SysAllocString() ou SysAllocStringLen() d'affecter le BSTR

Première exception chance à $ 75A9FBAE. Exception classe EAccessViolation avec le message « Violation d'accès à l'adresse 75A409A4 dans le module 'rpcrt4.dll'

  1. l'erreur provient de Rpcrt4.dll

  2. EAccessViolation est principalement causée par l'accès à un objet null, étape par votre marque de code vous que tous les objets sont des objets valides.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top