2011-06-06 71 views
0

我试图做一个RPC调用该请求2号和RPC服务器字符串返回一个字符串,该IDL看起来像这样:从Win32的RPC调用

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调用返回一个字符串的正确方法是什么?

感谢, Ĵ

+0

在通话或退回过程中发生错误吗?即'GetCurrentStatus'实际上是否执行服务器端? – 2011-06-06 18:44:12

回答

0

如果在这个问题上是有选择的,使用BSTR(即SysAllocString)。 RPC知道所有关于这种数据类型以及如何复制它并找到它的长度。

仅有

[out, retval] BSTR* pstrName 

就足够了,没有单独的长度参数需要的。

+1

我可以使用BSTR我想,但我宁愿明白我做错了什么,所以我可以避免将来出现这样的问题。 – JWood 2011-06-06 18:35:01

+0

@JWood:RPC假定调用者提供的缓冲区。 '[out]'仅仅意味着数据不会被正向复制。我认为传递'wchar_t'数组的方式是'[in,out] UINT * nLength,[out,size_is(* nLength)] LPWSTR szName'(注意它不是双指针),但是我出来了与DCOM一起练习。 – 2011-06-06 18:39:26

+0

http://msdn.microsoft.com/en-us/library/aa367164.aspx我不确定你做错了什么。 – 2011-06-06 18:42:41

-1

如果你写:

*nLength = name.length(); 

我相信你需要

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

特别是,如果你有一个空(长度为零)的字符串,然后返回一个size_is(0)阵列是不合法的 - - 所以您必须为字符串终止NUL(L'\0')添加空格。

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

+0

绝对不是。 'size_is'“表示分配大小,在** elements **”中。 http://msdn.microsoft.com/en-us/library/aa367164.aspx – 2011-06-06 19:27:06

+0

好点。他仍然错过了\ 0的+1,并且我支持他希望手动执行此操作,而不是使用BSTR。 – 2011-06-06 20:45:37

0

服务器无法传递字符串值返回给客户端,因为它不知道如何马歇尔字符串..

当您使用BSTR类型,服务器知道该字符串的长度。 BSTR的前面必须有一个4字节的长度字段,并由一个空的2字节字符结尾。