2

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

これはOS 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);
};

COMサーバーの関数は次のようになります

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

COMクライアントでは、この関数を次のように呼び出しています

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

$75A9FBAE でエラー First chance exception を取得します。メッセージ「モジュール 'RPCRT4.dll' のアドレス 75A409A4 でのアクセス違反」を伴う例外クラス EAccessViolation。アドレス FFFFFFF8' の読み取り。プロセス Project1.exe (2296)

整数を返したい場合は、うまくいきます。ワイドストリングを返す方法は?

4

5 に答える 5

1

これを処理する正しい方法は次のとおりです。

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

safecall次に、インターフェースの Delphi 宣言 (TypeLibrary 自体ではなく) でDelphi の呼び出し規約を使用することにより、少し簡略化できます。

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);
于 2010-11-18T03:09:10.703 に答える
1

Delphi に変換を自動的に実行させます。キャストしないでください。メモリ レイアウトに互換性があるため、(ansi) 文字列を PChar にキャストできますが、文字列をワイド文字列に、またはその逆にキャストすることはできません。一方を他方に割り当てると、Delphi は変換を実行します。

Delphi < 2009 で

var
S: string;
W: WideString;
...
S := W;  // Conversion, WideString -> AnsiString;
W := S; // Conversion, AnsiString -> WideString
于 2010-11-15T13:04:39.347 に答える
1

HRESULT 以外の戻り値を使用しないでください。代わりに、戻り値を出力パラメーターとしてパラメーター リストに入れます。

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

このように、COM メモリ マネージャー IMalloc (純粋な COM には CoTaskMemAlloc、オートメーションには SysAllocString) も使用する必要があります。

于 2010-11-15T12:53:44.110 に答える
0

BSTRを使用SysAllocString()または割り当てる必要があります。SysAllocStringLen()

于 2010-11-15T11:21:37.023 に答える
0

$75A9FBAEでの最初のチャンスの例外。メッセージ'RPCRT4.dll'のアドレス75A409A4でのアクセス違反を伴う例外クラスEAccessViolation

  1. エラーはRPCRT4.dllから来ています

  2. EAccessViolationは主に、nullオブジェクトにアクセスすることによって発生します。コードをステップ実行して、すべてのオブジェクトが有効なオブジェクトであることを確認してください。

于 2010-11-16T05:17:30.793 に答える