【问题标题】:Return a string from Win32 RPC call从 Win32 RPC 调用返回一个字符串
【发布时间】:2011-09-09 12:40:48
【问题描述】:

我正在尝试进行 RPC 调用,该调用从 RPC 服务器请求 2 个数字和一个字符串,IDL 如下所示:

void GetCurrentStatus([in] handle_t hBinding, [out, ref] DWORD *dwRef1, [out, ref] DWORD *dwRef2, UINT *nLength, [out, size_is(, *nLength)] LPWSTR *pszName);

在服务器端调用中我这样做:

// name = std::wstring
*pszName = (wchar_t*)midl_user_allocate(name.length()+1 * sizeof(wchar_t));
_tcscpy(*pszName, name.c_str());
*nLength = name.length();

但是任何从客户端调用的尝试都不会返回错误The array bounds are invalid.

从 RPC 调用返回字符串的正确方法是什么?

谢谢, J

【问题讨论】:

  • 是调用还是返回时出现错误?即GetCurrentStatus 是否实际执行服务器端?

标签: c++ windows winapi rpc


【解决方案1】:

如果您对此有选择权,请使用BSTR(即SysAllocString)。 RPC 知道所有关于这种数据类型以及如何复制它并找到它的长度。

只是

[out, retval] BSTR* pstrName

足够了,不需要单独的长度参数。

【讨论】:

  • 我想我可以使用 BSTR,但我宁愿了解我做错了什么,以便将来避免此类问题。
  • @JWood:RPC 假定调用者提供的缓冲区。 [out] 仅表示数据不会正向复制。我认为传递wchar_t 数组的方法是[in, out] UINT* nLength, [out, size_is(*nLength)] LPWSTR szName(注意它不是双指针),但我没有使用 DCOM。
  • msdn.microsoft.com/en-us/library/aa367164.aspx 我不确定你到底做错了什么。
  • 使用 SAFEARRAY 也是一个可行的选择。
  • Voight - 你说的完全正确,我希望能够在服务器端分配内存并将大小返回给调用者,但考虑到它是没有意义的。创建一个固定缓冲区并从客户端发送大小解决了这个问题。
【解决方案2】:

服务器无法将字符串值传递回客户端,因为它不知道如何编组字符串..

当你使用 BSTR 类型时,服务器知道字符串的长度。 BSTR 必须以 4 字节长度字段开头,并以单个空 2 字节字符终止。

【讨论】:

    【解决方案3】:

    你写的地方:

    *nLength = name.length();
    

    我相信你需要

    *nLength = (name.length() + 1) * sizeof(WCHAR);
    

    特别是,如果您有一个空(长度为零)字符串,则返回 size_is(0) 数组是不合法的——因此您必须为字符串终止的 NUL (L'\0') 添加空间。

    您还想以字节为单位提供大小,其中每个 Unicode 字符使用两个字节 - 因此您必须乘以字符大小。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-20
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    相关资源
    最近更新 更多