【发布时间】:2013-06-07 04:08:54
【问题描述】:
我试图在没有 MFC/ATL 帮助的情况下了解创建/使用 COM 组件以了解其内部工作原理。 我使用this codeguru article作为参考。以下是我遵循的步骤。
- 创建了 Wind32 Dll,
- 添加了一个MIDL文件并声明了接口
IAdd和库名DemoMath;使用 MIDL 编译器编译代码。 - 创建
CAddObj类派生IAdd接口,为IAdd和IUnknown接口提供实现。 - 创建的类
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(在调用者中),如果失败则对象被正确释放。