【问题标题】:How can I pass a variable-length string from an RPC server to the client?如何将可变长度字符串从 RPC 服务器传递到客户端?
【发布时间】:2012-05-03 06:26:03
【问题描述】:

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

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

[in, string] wchar_t* myString

MIDL 会处理内存分配魔法。像一种享受一样工作。

返回修改后的客户端字符串也很简单:

[in, out, string] wchar_t* myString

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

问题:

我需要将字符串从服务器返回到客户端。我不知道在客户端他们会有多大,所以客户端上的内存分配不是一个选项。

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

我尝试了什么:

除了许多其他的东西,我还尝试了 Microsoft 的 strout 示例中使用的技术。第一次调用 RPC 函数时它可以工作,但第二次调用时服务器崩溃。

【问题讨论】:

    标签: c++ winapi rpc idl


    【解决方案1】:

    MSDN 页面Multiple Levels of Pointers 让我走上了正轨。通过那里给出的示例和解释,我设法使其工作。主要部分如下:

    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 (stringSize * 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);
    

    【讨论】:

    • 您使用的是每个字符 2 个字节的 Unicode 字符串,因此您需要将字符串长度 * sizeof(wchar)...
    • @Remko 是的,没错,但我指的是下一行,我猜是:midl_user_allocate (stringSize * 2)
    猜你喜欢
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多