如何从 COM 服务器返回 WideString?
_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;
这会查看
[
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 服务器中的操作系统 Windows 函数,看起来就像
function TTMyCOM.MyDrawWS(a, b: Integer): WideString;
begin
Result := WideString(IntToStr(a+b));
end;
在 COM 客户端中,我正在调用此函数
Edit1.Text := String(MyCOM.MyDrawWS(1,1));
,并收到错误第一次机会异常,位于 $75A9FBAE。异常类 EAccessViolation,带有消息“模块‘RPCRT4.dll’中地址 75A409A4 处的访问冲突”。读取地址 FFFFFFF8'。 Process Project1.exe (2296)
如果我想返回 Integer,这是可行的。如何返回宽字符串?
This Interface at _TLB.pas file
// *********************************************************************//
// 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;
This looks at 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);
};
Function in COM server looks as
function TTMyCOM.MyDrawWS(a, b: Integer): WideString;
begin
Result := WideString(IntToStr(a+b));
end;
In COM Client i`m calling this function like
Edit1.Text := String(MyCOM.MyDrawWS(1,1));
and get error First chance exception at $75A9FBAE. Exception class EAccessViolation with message 'Access violation at address 75A409A4 in module 'RPCRT4.dll'. Read of address FFFFFFF8'. Process Project1.exe (2296)
If i want returning Integer, it`s works. How to return WideString?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
处理这个问题的正确方法如下:
然后可以通过在接口的 Delphi 声明(而不是 TypeLibrary 本身)中使用 Delphi 的
safecall
调用约定来稍微简化:The correct way to handle this is as follows:
Which can then be simplified a little by using Delphi's
safecall
calling convention in the Delphi declaration (not in the TypeLibrary itself) of the interface:让 Delphi 自动执行转换。别投。您可以将 (ansi) 字符串转换为 PChar,因为它们的内存布局是兼容的,但您不能将字符串转换为宽字符串,反之亦然。当您将一个分配给另一个时,Delphi 将执行转换。
在德尔福< 2009年
Let Delphi perform the conversions automatically. Don't cast. You can cast a (ansi)string to a PChar, because their memory layout are compatible, but you can't cast a string to a widestring or viceversa. Delphi will perfrom conversion when you assign one to the other.
In Delphi < 2009
不要使用 HRESULT 以外的返回值。而是将您的返回值作为输出参数放入参数列表中。
这样,你也被迫使用COM内存管理器IMalloc(CoTaskMemAlloc用于pur COM,SysAllocString用于Automation)。
Don't use return values other than HRESULT. Instead put your return value into parameter list as output parameter.
In this way, you are also forced to use COM memory manager IMalloc (CoTaskMemAlloc for pur COM, SysAllocString for Automation).
您需要使用
SysAllocString()
或SysAllocStringLen()
分配 BSTR。You need to use
SysAllocString()
orSysAllocStringLen()
to allocate the BSTR.第一次机会例外,价格为 75A9FBAE。异常类 EAccessViolation,带有消息“模块‘RPCRT4.dll’中地址 75A409A4 处的访问冲突
错误来自 RPCRT4.dll
EAccessViolation 主要是由访问引起的如果是 null 对象,请单步执行您的代码,确保所有对象都是有效对象。
First chance exception at $75A9FBAE. Exception class EAccessViolation with message 'Access violation at address 75A409A4 in module 'RPCRT4.dll'
the error is coming from RPCRT4.dll
EAccessViolation is mostly caused by accessing a null object, step through your code make sure all objects are valid objects.