如何将可变长度字符串从 RPC 服务器传递到客户端

How can I pass a variable-length string from an RPC server to the client?

本文关键字:服务器 RPC 客户端 字符串      更新时间:2023-10-16

我正在实现一个Windows系统服务,它充当RPC服务器和相应的客户端,两者都在C++中。我正在使用普通的Windows RPC功能。

将字符串从 RPC 客户端传递到服务器很容易。只需在 IDL 文件中声明函数参数,如下所示:

[in, string] wchar_t* myString

MIDL 将负责内存分配魔法。就像一种享受。

返回修改后的客户端字符串也很容易:

[in, out, string] wchar_t* myString

不过,这需要我在客户端正确调整字符串的大小。

问题:

我需要将字符串从服务器返回到客户端。我不知道客户端上的内存分配有多大,因此客户端上的内存分配不是一种选择。

我可以分配非常大的内存量,比如 10K,这个数量足以满足服务器可能返回的每个字符串。但这是对资源(内存、网络)的巨大浪费,我仍然无法确定服务器永远不需要返回更大的字符串。

我尝试过:

阿蒙斯特 我尝试了Microsoft的条纹样本中使用的技术。它在第一次调用 RPC 函数时有效,但在第二次调用时服务器崩溃。

MSDN 页面多级指针使我走上了正确的轨道。通过那里给出的示例和解释,我设法使其工作。部分如下:

IDL 文件:

error_status_t ReturnsString
(
   [out]                   long*     size,
   [out, size_is(, *size)] wchar_t** outString
);

服务器功能:

error_status_t ReturnsString (long* size, wchar_t** outString)
{
   wstring outStringWString = L"Return this to caller";
   int stringSize = sizeof(wchar_t) * (outStringWString.size() + 1);
   *outString = (wchar_t*) midl_user_allocate (stringSize * 2);
   wcscpy_s (*outString, stringSize, outStringWString.c_str());
   *size = outStringWString.size() + 1;
   return ERROR_SUCCESS;
}

我不知道为什么乘以二(字符串大小 * 2)是必要的,但它是必要的。如果省略,则会立即获得堆损坏。

客户端代码:

wchar_t** versionRPC = (wchar_t**) midl_user_allocate (sizeof(wchar_t*));
*versionRPC = NULL;     // Required to create a unique pointer
long stringSize = 0;
DWORD retVal = ReturnsString (&stringSize, versionRPC);
// Copy the returned string
wstring stringFromServer (*rpcString);
MIDL_user_free (*rpcString);
MIDL_user_free (rpcString);