CoCreateInstance返回E_NOINTERFACE,即使找到接口 [英] CoCreateInstance returning E_NOINTERFACE even though interface is found

查看:556
本文介绍了CoCreateInstance返回E_NOINTERFACE,即使找到接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个COM类 CMyCOMServer 在一个应用程序中实现 IMyInterface ,两者都有正确的GUID。 如果请求了IUnknown或IMyInterface,则CMyCOMServer :: QueryInterface 将返回S_OK(并转换为正确的类型)。



在同一台电脑上的另一个应用程序中,我调用:

  HRESULT hr = :: CoCreateInstance(__ uuidof CMyCOMServer),0,CLSCTX_SERVER,
__uuidof(IMyInterface),(void **)& pInterface);

返回E_NOINTERFACE。所以我假设我做错了,并在 CMyCOMServer :: QueryInterface 上添加了一个断点。我发现当调用 CoCreateInstance 时,不同接口会触发 QueryInterface 多次:




  • 首先,请求IUnknown - 没有问题

  • 然后,请求IMarshall等几个接口...这些不支持因此返回E_NOINTERFACE

  • 最后,请求IMyInterface。我验证QueryInterface返回S_OK并设置(IMyInterface *)this 作为接口指针



所以我的困惑是为什么调用CoCreateInstance是留下一个NULL指针和返回代码E_NOINTERFACE,当COM服务器应用程序清楚地返回我要求的接口?



EDIT:我的客户端应用程序在启动时调用CoInitialize(NULL),这没有什么区别。

解决方案

服务器在不同的进程中运行,或者在同一进程中不同的公寓,COM需要知道如何打包和传输参数,当你调用你的接口。这个过程称为封送处理。



如果您定义自定义接口,您需要使用以下方法之一实现封送处理。




  • 标准封送:让MIDL编译器生成代理
    和stub,您必须在系统上注册。

  • OLE自动化封送:您定义了一个自动化兼容的
    自定义界面,并使用
    marshaller已经是
    COM框架的一部分

  • 自定义封送:您实施IMarshal的方法



当你调试你的COM服务器时,虽然你看到你在调用QueryInterface返回你的自定义接口,它不会跨越过程边界因为COM无法找出如何封送该接口,因此客户端会看到E_NOINTERFACE。



UPDATE(根据您的评论)

如果这是一个现有的COM服务器应用程序,那么你可能已经有一个代理/存根。您需要在客户端和服务器上注册此。这是否是你在一台新机器上测试这个,你只是忘了注册这个?要注册你只需在代理/存根dll上执行regsvr32。


I have a COM class CMyCOMServer implementing IMyInterface in one application, both with correct GUIDs. CMyCOMServer::QueryInterface will return S_OK (and cast itself to the right type) if IUnknown or IMyInterface is requested, otherwise it returns E_NOINTERFACE.

In another app on the same PC, I call:

HRESULT hr = ::CoCreateInstance(__uuidof(CMyCOMServer), 0, CLSCTX_SERVER,
 __uuidof(IMyInterface ),(void **)&pInterface);

It returns E_NOINTERFACE. So I assumed I was doing something wrong and added a breakpoint on CMyCOMServer::QueryInterface. I found that when CoCreateInstance is called, QueryInterface is triggered several times for different interfaces:

  • First, IUnknown is requested - no problem
  • Then, several interfaces like IMarshall etc are requested... these are not supported so E_NOINTERFACE is returned
  • Finally, IMyInterface is requested. I verify QueryInterface returns S_OK and sets (IMyInterface *)this as the interface pointer, as expected

So my confusion is why the calling CoCreateInstance is leaving me a NULL pointer and return code of E_NOINTERFACE, when the COM server app is clearly returning the interface I ask for?

EDIT: my client app calls CoInitialize(NULL) at startup, this makes no difference.

解决方案

If your COM server is running in a different process, or a different apartment in the same process, COM needs to know how to package and transmit parameters when you make calls to your interface. This process is called "marshaling".

If you define a custom interface, you need to implement marshaling for it using one of the following approaches.

  • Standard marshaling: have the MIDL compiler to generate a proxy and stub which you must register on the system. This is probably the best option since you have already defined your interface.
  • OLE Automation marshaling: you define an automation compatible custom interface and use the marshaller which is already part of the COM framework
  • Custom marshaling: you implement the methods of IMarshal

When you are debugging your COM server, although you see that you are returning your custom interface in the call to QueryInterface, it does not make it across the process boundary because COM cannot figure out how to marshal that interface, hence the client sees E_NOINTERFACE.

UPDATE (based on your comment)

If this is an existing COM server app then you probably already have a proxy/stub. You need to register this on both the client and server. Could it be that you were testing this on a new machine(s) and you simply forgot to register this? To register you simply do regsvr32 on the proxy/stub dll.

这篇关于CoCreateInstance返回E_NOINTERFACE,即使找到接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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