COM 如何选择如何编组接口?
据我了解,在 COM 中实现编组有三种方法:
- typelib 编组
- 代理/存根编组
- 通过对象实现 IMarshal
现在组件消费者(用户)如何选择使用哪一种?它是自行决定并使用首选方式,还是调用某些内置函数并为其解决问题?
我目前遇到以下情况:我的组件实现了一个自定义接口 ICustomInterface
,该接口也由另一家公司的组件实现。我的组件没有类型库并且没有实现 IMarshal。系统注册表包含 HKCR\Interface{uuidof(ICustomInterface)}\ProxyStubClsid32 项,其中包含代理/存根的 GUID,可以追溯到该其他公司提供的库。
现在,当我的组件使用者初始化我的组件时,它会调用 QueryInterface() 向我的组件请求 IMarshal,当返回 E_NOINTERFACE 时,它什么也不做。这是为什么——为什么其他公司的代理/存根库没有启动?
As I get it there're three ways to implement marshalling in COM:
- typelib marshalling
- proxy/stub marshalling
- implementing IMarshal by the object
now how does the component consumer (user) choose which one will be used? Does it decide on its own and use the preferred way or does it call some built-in function and it solves the problem for it?
I currently experience the following: my component implements a custom interface ICustomInterface
that is also implemented by a component from another company. My component doesn't have a typelib and doesn't implement IMarshal. The system registry contains the HKCR\Interface{uuidof(ICustomInterface)}\ProxyStubClsid32 key with a GUID of the proxy/stub that can be traced to a library provided by that other company.
Now when my component consumer initializes my component it calls QueryInterface() requesting IMarshal from my component and when returned E_NOINTERFACE it just does nothing. Why is this - why doesn't proxy/stub library from the other company kick in?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您通过在
HKCR\Interfaces\ 下添加其 CLSID
(其中 {iid} 是接口的 GUID)。您还需要注册一个类型库,以便运行时提取参数信息,并且您只能使用特定类型的子集。 这里还有更多(旧)信息 和 此处。{00020424-0000-0000-C000-000000000046}
将接口标记为使用标准封送拆收器,COM 运行时将使用 typelib (oleautomation) 封送处理{iid}\ProxyStubClsid如果您想使用由 MIDL 编译器从 IDL 生成的自定义代理/存根,则需要将接口注册表项更改为该代理对象的 CLSID。这使您能够使用更广泛的类型,例如“原始”数组。
如果您支持
IMarshal
,那么将优先使用这两种机制。这意味着您可以更改对象以聚合自由线程封送拆收器(使用其 IMarshal 实现),而无需更改注册表中的任何内容。这将避免创建任何代理。希望这有帮助。
The COM runtime will use typelib (oleautomation) marshalling if you mark your interface as using the standard marshaler by adding its CLSID
{00020424-0000-0000-C000-000000000046}
underHKCR\Interfaces\{iid}\ProxyStubClsid
(where {iid} is the GUID of your interface). You'll need to have a typelibrary registered too, in order for the runtime to extract the parameter information, and you can only use a certain subset of types. There's some more (old) information here and here.If you want to use a custom proxy/stub, as generated by the MIDL compiler from your IDL, then you'll need to change the interface registry entry to be the CLSID of that proxy object instead. This enables you to use a wider range of types, e.g. "raw" arrays.
If you support
IMarshal
then that's what'll be used in preference to either of these mechanisms. This means you can change your object to aggregate the free-threaded marshaler (using its implementation ofIMarshal
) without having to change anything in the registry. This will avoid any proxies being created.Hope this helps.
我对此有点生疏,但是你的项目中有一个名为blindquery的函数吗? (如果您创建了 C++ ATL 项目,则通常由向导声明)。函数内的断点。由于代码错误,由向导生成的函数经常会出现 queryinterface 返回 E_NOINTERFACE 的问题。
从我的旧项目中编辑(找到示例代码) _盲目查询
I am a bit rusty at this, but do you have a function named blindquery in your project ? (its usually declared by the wizard if you created a C++ ATL project). Breakpoint inside the function. The function is generated by the wizard often has problems with queryinterface returning E_NOINTERFACE due to buggy code.
edit (found sample code) from my old project _blindquery