我在C#中为COM-Server定义了这个接口:
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("58C77969-0E7D-3778-9999-B7716E4E1111")]
public interface IMyInterface
{
string MyName { get; }
}该接口是在Delphi XE5程序中导入和实现的。
进口如下所示:
IMyInterface = interface(IUnknown)
['{58C77969-0E7D-3778-9999-B7716E4E1111}']
function Get_MyName (out pRetVal: WideString): HResult; stdcall;
end;这样的实施:
type
TMyImpl = class(TInterfacedObject, IMyInterface)
public
function Get_MyName (out pRetVal: WideString): HResult; stdcall;
end;
function TMyImpl.Get_MyName (out pRetVal: WideString): HResult;
var
s: string;
begin
s:=''; // empty!
pRetVal:=s;
result:=S_OK;
end;当我像这样从c#调用服务器时:
var server = new Server();
string s = server.MyName;然后s是NULL,而不是例外的空字符串。
如何强制空字符串作为空字符串在COM中传输,而不是以封送处理替换为NULL?
发布于 2016-01-08 14:14:09
Delphi将空字符串实现为零指针(参见System._NewUnicodeString)。您可以手动分配一个空的COM兼容字符串:
function TMyImpl.Get_MyName(out pRetVal: WideString): HResult;
var
BStr: TBstr;
begin
BStr := SysAllocString('');
if Assigned(BStr) then
begin
Pointer(pRetVal) := BStr;
Result := S_OK;
end
else
Result := E_FAIL;
end;或者您可以创建一个帮助函数:
function EmptyWideString: WideString;
begin
Pointer(Result) := SysAllocString('');
end;发布于 2016-01-08 14:15:30
在Delphi端试试这个:
IMyInterface = interface(IUnknown)
['{58C77969-0E7D-3778-9999-B7716E4E1111}']
function Get_MyName (out pRetVal: BSTR): HResult; stdcall;
end;
function TMyImpl.Get_MyName (out pRetVal: BSTR): HResult;
begin
pRetVal := SysAllocString('');
Result := S_OK;
end;如果您希望处理SysAllocString失败的情况,那么您可以这样编写它:
function TMyImpl.Get_MyName (out pRetVal: BSTR): HResult;
begin
pRetVal := SysAllocString('');
Result := IfThen(Assigned(pRetVal), S_OK, E_FAIL);
end;尽管就我个人而言,我觉得在调用SysAllocString('')时检查错误是合理的。
我的猜测是,Delphi将空WideString编组为零指针,而不是空BSTR。在我看来这是个缺陷。
https://stackoverflow.com/questions/34678086
复制相似问题