我有一个使用Microsoft RPC进行进程间通信的程序。当使用[in,string]参数调用方法时(MIDL表示法):
interface IOurInterface
{
error_status_t rpcMethod( [in, string] const WCHAR* parameter );
}
被调用它通常是成功的。但是如果参数字符串足够长(超过大约300万个字符),则调用将失败并显示RPC_S_CALL_FAILED_DNE(“远程过程调用失败并且未执行。”)。这肯定取决于字符串长度。如果字符串在限制范围内,则相同条件下的相同调用始终成功,如果字符串较长,则始终失败。看起来这个限制依赖于系统或机器。
是否有人观察过此类行为以及可能的解决方案(不缩短参数)?
答案 0 :(得分:1)
之前我已经观察过该消息,但我不认为这是同一个原因 - “未执行”是一个通用的RPC错误,可能是由许多事情引起的。
在我们的特殊情况下,这是因为我们过于努力地锤击WMI并且没有清理我们的物体。但在你的情况下,它似乎是一个不同的原因。
我知道你说你不想缩短参数,但这可能是你前进的唯一方法。我很难想象你需要在RPC调用中发送6M的情况。也许如果你解释其背后的原因,我们可以进一步提供帮助。
基于迄今为止评论的其他可能性:
1 /细分。
让RPC调用限制通过线路传输的数据量。这可以通过在源处对消息进行分段并在目的地重建它来完成,例如有三个参数(您可以让服务器在另一个RPC调用中发出消息标识符,或者找到其他方法以确保没有两个客户端具有相同的ID): - 消息标识符(用于将消息段绑在一起)。 - 最后一个标志(开始重建过程)。 - 有限大小的部分(例如,1M)。
2 /压缩。
由于XML是文本,因此压缩已经成熟。 7zip库是我在尺寸减小方面看到的最好的。这是否足够快是另一回事。
通过更改注册表来修复3 / 可能的。
查看HKLM / Software / Microsoft / Rpc注册表区域以获取RpcMaxSize密钥。有几个网站我用谷歌搜索建议将其设置为-1将删除大小限制(全局,所以要小心)。
注册界面时,4 / 可能修复。
您可以在RpcServerRegisterIf2()
的特定界面上显然达到与(3)相同的效果。
答案 1 :(得分:1)
每个RPC调用的大小通常受到各种因素的限制,例如传输限制(例如:UDP上的数据包大小,比特率/最大延迟)
你可以做的是将你的字符串分成数据包并通过多次调用发送它,
或打开一个额外的tcp套接字来发送数据并用当前的RPC
控制它