如何从COM服务器返回Widestring?
-
10-10-2019 - |
题
此接口_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窗口
[
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。异常类Eaccessviolation带有消息“访问违规的地址75A409A4”中的“ rpcrt4.dll”中的“访问违规”。阅读地址fffffff8'。 Process Project1.exe(2296)
如果我想返回整数,那就可以了。如何返回Widestring?
解决方案
处理此问题的正确方法如下:
[
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;
然后可以通过使用Delphi的 safecall
在接口的Delphi声明(不在TypeLibrary本身中)中调用约定:
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);
其他提示
除了hresult以外,不要使用返回值。而是将您的返回值作为输出参数列入参数列表。
function MyDrawWS(a: Integer; b: Integer; out str : WideString): HRESULT; stdcall;
这样,您还被迫使用COM内存管理器Imalloc(用于PUR com的CotaskMemalloc,用于自动化的SysallocString)。
让Delphi自动执行转换。不要铸造。您可以将(ANSI)字符串施放到PCHAR上,因为它们的内存布局是兼容的,但是您不能将字符串施加到宽大或viceversa。当您将一个分配给另一个时,Delphi将经过转换。
在Delphi <2009
var
S: string;
W: WideString;
...
S := W; // Conversion, WideString -> AnsiString;
W := S; // Conversion, AnsiString -> WideString
您需要使用 SysAllocString()
或者 SysAllocStringLen()
分配BSTR。
第一个机会例外,$ 75A9FBAE。异常类eaccessviolation带有消息“违反访问权限的地址75A409A4”中的模块'rpcrt4.dll'
错误来自RPCRT4.DLL
eaccessviolation主要是由访问空对象引起的,逐步浏览代码,确保所有对象都是有效的对象。
不隶属于 StackOverflow