首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >COM Server发送空字符串,该字符串被转换为空指针

COM Server发送空字符串,该字符串被转换为空指针
EN

Stack Overflow用户
提问于 2016-01-08 13:19:35
回答 2查看 175关注 0票数 3

我在C#中为COM-Server定义了这个接口:

代码语言:javascript
复制
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("58C77969-0E7D-3778-9999-B7716E4E1111")]
public interface IMyInterface    
{
    string MyName { get; }
}

该接口是在Delphi XE5程序中导入和实现的。

进口如下所示:

代码语言:javascript
复制
IMyInterface = interface(IUnknown)
  ['{58C77969-0E7D-3778-9999-B7716E4E1111}']
  function Get_MyName (out pRetVal: WideString): HResult; stdcall;
end;

这样的实施:

代码语言:javascript
复制
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#调用服务器时:

代码语言:javascript
复制
var server = new Server();
string s = server.MyName;

然后s是NULL,而不是例外的空字符串。

如何强制空字符串作为空字符串在COM中传输,而不是以封送处理替换为NULL?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-08 14:14:09

Delphi将空字符串实现为零指针(参见System._NewUnicodeString)。您可以手动分配一个空的COM兼容字符串:

代码语言:javascript
复制
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;

或者您可以创建一个帮助函数:

代码语言:javascript
复制
function EmptyWideString: WideString;
begin
  Pointer(Result) := SysAllocString('');
end;
票数 3
EN

Stack Overflow用户

发布于 2016-01-08 14:15:30

在Delphi端试试这个:

代码语言:javascript
复制
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失败的情况,那么您可以这样编写它:

代码语言:javascript
复制
function TMyImpl.Get_MyName (out pRetVal: BSTR): HResult;
begin
  pRetVal := SysAllocString('');
  Result := IfThen(Assigned(pRetVal), S_OK, E_FAIL);
end;

尽管就我个人而言,我觉得在调用SysAllocString('')时检查错误是合理的。

我的猜测是,Delphi将空WideString编组为零指针,而不是空BSTR。在我看来这是个缺陷。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34678086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档