据我所知,在COM中实现编组有三种方法:
- 排字编组
- 代理/存根编组
- 通过对象实现IMarshal
现在组件 * 消费者 *(用户)如何选择使用哪一个?它自己决定并使用首选方式,还是调用一些内置函数并解决问题?
我目前遇到以下情况:我的组件实现了一个自定义接口ICustomInterface
,该接口也由另一家公司的组件实现。我的组件没有类型库,也没有实现IMarshal。系统注册表包含HKCR\Interface{uuidof(ICustomInterface)}\ProxyStubClub32键,该键带有一个代理/存根的标识符,该标识符可以跟踪到该另一家公司提供的库。
现在,当我的组件消费者访问我的组件时,它调用QueryInterface()从我的组件请求IMarshal,当返回E_NOINTERFACE时,它什么也不做。为什么会这样-为什么其他公司的代理/存根库不起作用?
2条答案
按热度按时间xt0899hw1#
COM运行时将使用typelib(oleautomation)封送,如果您通过在
HKCR\Interfaces\{iid}\ProxyStubClsid
下添加其CLSID{00020424-0000-0000-C000-000000000046}
,将接口标记为使用标准封送拆收器(其中{iid}是接口的类型标识符)。您还需要注册一个类型标识符,以便运行时提取参数信息,你只能使用类型的一个子集。还有一些(旧的)信息here和here。如果你想使用一个自定义的代理/存根,由MIDL编译器从你的IDL生成,那么你需要将接口注册表条目改为该代理对象的CLSID。这使你能够使用更广泛的类型,例如“raw”数组。
如果你支持
IMarshal
,那么它将优先于这两种机制。这意味着你可以改变你的对象来聚合自由线程的封送拆收器(使用它的IMarshal
实现),而不必改变注册表中的任何内容。这将避免创建任何代理。希望这对你有帮助。
rwqw0loc2#
我对此有点生疏,但你的项目中是否有一个名为blindquery的函数?(如果你创建了一个C++ ATL项目,它通常由向导声明)。函数内部的断点。该函数由向导生成,由于代码错误,queryinterface经常返回E_NOINTERFACE。
从我的旧项目中编辑(找到示例代码)_ blindquery
字符串