COM如何选择如何编组接口? [英] How does COM select how to marshal an interface?

查看:12
本文介绍了COM如何选择如何编组接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,在 COM 中实现编组的三种方法:

As I get it there're three ways to implement marshalling in COM:

  • typelib 编组
  • 代理/存根编组
  • 通过对象实现 IMarshal

现在组件consumer(用户)如何选择使用哪一个?它是自行决定并使用首选方式,还是调用一些内置函数并为它解决问题?

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?

我目前遇到以下情况:我的组件实现了一个自定义接口ICustomInterface,该接口也由另一家公司的组件实现.我的组件没有类型库,也没有实现 IMarshal.系统注册表包含 HKCRInterface{uuidof(ICustomInterface)}ProxyStubClsid32 键,其代理/存根的 GUID 可以追溯到其他公司提供的库.

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 HKCRInterface{uuidof(ICustomInterface)}ProxyStubClsid32 key with a GUID of the proxy/stub that can be traced to a library provided by that other company.

现在,当我的组件使用者初始化我的组件时,它调用 QueryInterface() 从我的组件请求 IMarshal,而当返回 E_NOINTERFACE 时它什么也不做.为什么会这样 - 为什么其他公司的代理/存根库不启动?

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?

推荐答案

如果您通过添加其 CLSID {00020424-0000-0000 将接口标记为使用标准编组器,则 COM 运行时将使用 typelib (oleautomation) 编组-C000-000000000046}HKCRInterfaces{iid}ProxyStubClsid 下(其中 {iid} 是您界面的 GUID).您还需要注册一个类型库,以便运行时提取参数信息,并且您只能使用特定类型的子集.还有更多(旧)信息这里这里.

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} under HKCRInterfaces{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.

如果您想使用 MIDL 编译器从您的 IDL 生成的自定义代理/存根,那么您需要将接口注册表项更改为该代理对象的 CLSID.这使您可以使用更广泛的类型,例如原始"数组.

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.

如果您支持 IMarshal,那么将优先使用这两种机制.这意味着您可以更改您的对象以聚合自由线程封送拆收器(使用它的 IMarshal 实现),而无需更改注册表中的任何内容.这将避免创建任何代理.

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 of IMarshal) without having to change anything in the registry. This will avoid any proxies being created.

希望这会有所帮助.

这篇关于COM如何选择如何编组接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆