这个问题建立在this问题
中链接的代码之上在我对自定义编组的研究中,我遇到了这篇文章,它为我提供了在没有 Visual Studio 帮助的情况下创建自己的代理/存根所需的所有见解。
这里是完整项目的链接,请按照this问题中完全相同的说明来启动和运行服务器和客户端
那么问题出在哪里?
首先让我告诉你什么不是问题
两端的一切都完全按照计划进行设置,直到随机发生错误。当我说随机时,我是认真的,
我已经调试了一天多了,但仍然无法确定为什么这些代码段总是随机失败,这就是为什么我在这里寻求调试帮助。
如果有人确实设法让此代码工作,那么 Com 客户端应该与 COM 服务器通信,您将在客户端看到类似这样的输出
Click 1
Scroll 10
Key Pressed 5
Key Released 10
基本上,COM 服务器将这些字符串作为字符数组从 STUB 发送到 PROXY,代理最终打印接收到的值。
请注意,使用生成的 RPC 代理/存根的标准封送不是 Visual Studio 功能,它由 Windows SDK 提供。 MIDL,.IDL 编译器是一个 SDK 工具,可生成默认的 P/S 文件(.c、.h 等),因此它确实是 Windows 功能。
Visual Studio(通用工具,通常与 ATL 结合使用)只是为您简化了 MIDL 的调用。
现在,在没有生成的代理/存根的情况下进行标准封送仍然是可能的,但我不会推荐它,除非您有充分的理由这样做。原因包括在来回传输参数时进行非常具体的优化,您知道您可以使用这些优化,但您知道系统不能。例如,生成的 RPC 代码将使用大块内存传输特定类型的参数(如字符串或字节数组),并且您可以以不同的方式传输(如特定上下文内部某些内容的共享句柄)。
它现在可以在提到的存储库中运行,所以让我们回到一些必须修复的故障:
IPSFactoryBuffer::CreateProxy方法的
pUnkOuter
参数,因此至少AddRef
,完成后Release
。pUnkOuter
委托给任何其他接口的所有 QueryInterface
调用,而不是 IRpcProxyBuffer
并且 不是 代理接口:IMouse
、IKeyboard
等。(这些必须当然由代理实现者实现)pUnkOuter
,这就是代理端发生的情况。iMethod
调用之后设置 GetBuffer
,则永远不会到达存根的 IRpcStubBuffer::Invoke,并且代理将在 SendReceive 方法的
RPC_E_INVALID_HEADER
out 参数中收到
pStatus
错误 (0x80010111) 。请注意,“Inside COM+”一书在这里是错误的(或者也许事情已经发生了变化,但我对此表示怀疑)。其他备注:
AddRef
和 Release
实现线程安全,例如使用 InterlockedIncrement 和 InterlockedDecrement 而不是 ++
和 --
运算符。好的练习,让每个人都更容易。AddRef
将接口返回给调用者(与 COM 一样)。