【问题标题】:COM - Implementing DllGetClassObjectCOM - 实现 DllGetClassObject
【发布时间】:2013-06-07 04:08:54
【问题描述】:

我试图在没有 MFC/ATL 帮助的情况下了解创建/使用 COM 组件以了解其内部工作原理。 我使用this codeguru article作为参考。以下是我遵循的步骤。

  • 创建了 Wind32 Dll,
  • 添加了一个MIDL文件并声明了接口IAdd和库名DemoMath;使用 MIDL 编译器编译代码。
  • 创建CAddObj 类派生IAdd 接口,为IAddIUnknown 接口提供实现。
  • 创建的类 CAddFactory 派生自 IClassFactory 接口;为 IClassFactory 方法提供了实现。

现在创建DllGetClassObject 为客户端提供调用此函数以获取类工厂实例的选项。

以下是代码:

#include "stdafx.h"
#include <objbase.h>
#include "AddObjFactory.h"
#include "IAdd_i.c"
STDAPI DllGetClassObject(const CLSID& clsid,
                         const IID& iid,
                         void** ppv)
{
    //
    //Check if the requested COM object is implemented in this DLL
    //There can be more than 1 COM object implemented in a DLL
    //

    if (clsid == CLSID_AddObject)
    {
        //
        //iid specifies the requested interface for the factory object
        //The client can request for IUnknown, IClassFactory,
        //IClassFactory2
        //
        CAddFactory *pAddFact = new CAddFactory;
        if (pAddFact == NULL)
            return E_OUTOFMEMORY;
        else
        {
            return pAddFact->QueryInterface(iid , ppv);
        }
    }

    //
    //if control reaches here then that implies that the object
    //specified by the user is not implemented in this DLL
    //

    return CLASS_E_CLASSNOTAVAILABLE;
}

现在应该在哪里定义CLSID_AddObject 常量 还是编译 MIDL 文件时生成的(我没找到)?

【问题讨论】:

  • 在许多 C++98 标准之前的编译器中,new 在失败时返回零。然而,十多年来情况并非如此,即使在微软的编译器上也是如此。您需要捕获 std::bad_alloc 异常。
  • 您的DllGetClassObject() 实现中存在内存泄漏。 QueryInterface() 如果成功,则增加引用计数。如果失败,您的对象不会被释放。您应该从引用计数为 1 的对象开始,对其调用QueryInterface(),然后对其调用Release(),无论QueryInterface() 是成功还是失败。这样,如果成功,当DllGetClassObject() 退出时引用计数仅为1(在调用者中),如果失败则对象被正确释放。

标签: c++ winapi dll com


【解决方案1】:

coclass IDL 项目通常会为您提供 CLSID:

library Foo
{
//...
    [
        //...
    ]
    coclass AddObject
    {
        //...
    };

那么在你的“IAdd_i.c”中你已经包含了:

MIDL_DEFINE_GUID(CLSID, CLSID_AddObject, ...);

这就是CLSID_AddObject的定义。

【讨论】:

  • 感谢您的回答,您是说 coclass AddObject 中的接口 IAdd 而不是 IAddObject(因为这不存在)?我认为需要有另一个 uuid 我应该将 coclass 与之关联,对吧?
  • IAddObject 无关紧要,只是典型的声明。我更新为只留下相关部分。 coclass 本身很重要。
  • @Hans Passant 我不明白你为什么删除你的答案!
猜你喜欢
  • 2011-03-28
  • 1970-01-01
  • 2015-10-03
  • 2011-01-10
  • 1970-01-01
  • 2011-09-29
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多