VS2005 MFC 开发COM 遇到的问题,高手请进.

VCHelp之乐天蛋黄派 2013-01-23 10:41:53
我用VS2005 生成一个MFC DLL(支持自动化).

添加一个继承自CCmdTarget的类, 然后使用MFC标准方法添加接口与类厂(代码如下).问题是在客户程序中用CoCreateInstance创建组件的时候总是返回E_OUTOFMEMORY(在调用前已初始化COM库). 我跟踪程序,发现类厂已经被创建,但类厂却没有创建组件. 由于是标准的类厂实现, 无法跟踪到MFC类厂的代码中. 所以很迷茫.

另外还有一个现象是, 用VC6.0生成一个扩展DLL项目,把这些代码原封不动拷入,编译生成组件. 客户程序就可以正常创建组件,并能正常调用接口.

还有就是我注意到VC6.0没有生成的IDL文件,而VS2005却自动维护一个IDL文件,这个IDL文件中只有组件描述, 没有接口描述, 我手动加上接口描述后, 可调用还是不成功.

1, 接口定义:

#include "stdafx.h"

class ICom2Interface1: public IUnknown
{
public:
virtual void _stdcall Function1() = 0;
virtual void _stdcall Function2() = 0;
};

class ICom2Interface2: public IUnknown
{
public:
virtual void _stdcall Function1() = 0;
virtual void _stdcall Function2() = 0;
};

2, 组件定义:

class CComponetObj : public CCmdTarget
{
DECLARE_DYNCREATE(CComponetObj)
CComponetObj();

protected:
virtual ~CComponetObj();

public:
BEGIN_INTERFACE_PART (TmpObj1, ICom2Interface1)
INIT_INTERFACE_PART (CComponetObj, TmpObj1)
STDMETHOD_(void,Function1)();
STDMETHOD_(void,Function2)();
END_INTERFACE_PART_STATIC(TmpObj1)

BEGIN_INTERFACE_PART (TmpObj2, ICom2Interface2)
INIT_INTERFACE_PART (CComponetObj, TmpObj2)
STDMETHOD_(void,Function1)();
STDMETHOD_(void,Function2)();
END_INTERFACE_PART_STATIC(TmpObj2)

DECLARE_MESSAGE_MAP()
DECLARE_INTERFACE_MAP()
DECLARE_OLECREATE(CComponetObj)

};


组件的实现代码:

// {037439C0-3F86-4309-A129-B3E8E6E94B2F}
extern "C" const GUID IID_ICom2Interface1 =
{ 0x37439c0, 0x3f86, 0x4309, { 0xa1, 0x29, 0xb3, 0xe8, 0xe6, 0xe9, 0x4b, 0x2f } };

// {167722E4-EDF3-4ea8-B085-3A82B2BF8AF1}
extern "C" const GUID IID_ICom2Interface2 =
{ 0x167722e4, 0xedf3, 0x4ea8, { 0xb0, 0x85, 0x3a, 0x82, 0xb2, 0xbf, 0x8a, 0xf1 } };

IMPLEMENT_DYNAMIC(CComponetObj, CCmdTarget)

IMPLEMENT_OLECREATE(CComponetObj, "COM_2.Object",
0xe3ee73ee, 0xced5, 0x429b, 0x9a, 0x6f, 0x9d, 0x32, 0xe1, 0x17, 0x6b, 0x8c);

CComponetObj::CComponetObj()
{
wprintf (L"Constructing CComponetObj!\r\n");
}

CComponetObj::~CComponetObj()
{
}

BEGIN_MESSAGE_MAP(CComponetObj, CCmdTarget)
END_MESSAGE_MAP()

BEGIN_INTERFACE_MAP(CComponetObj, CCmdTarget)
INTERFACE_PART (CComponetObj, IID_ICom2Interface1, TmpObj1)
INTERFACE_PART (CComponetObj, IID_ICom2Interface2, TmpObj2)
END_INTERFACE_MAP()


STDMETHODIMP_(ULONG) CComponetObj::XTmpObj1::AddRef()
{
METHOD_PROLOGUE_EX_(CComponetObj, TmpObj1)
return (ULONG)pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) CComponetObj::XTmpObj1::Release()
{
METHOD_PROLOGUE_EX_(CComponetObj, TmpObj1)
return (ULONG)pThis->ExternalRelease();
}

STDMETHODIMP CComponetObj::XTmpObj1::QueryInterface(REFIID iid, LPVOID * ppv)
{
METHOD_PROLOGUE_EX_(CComponetObj, TmpObj1)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppv);
}

STDMETHODIMP_(void) CComponetObj::XTmpObj1::Function1()
{
METHOD_PROLOGUE_EX_(CComponetObj, TmpObj1)
wprintf (L"ICom2Interface1->Function1 has been called.\r\n");
}

STDMETHODIMP_(void) CComponetObj::XTmpObj1::Function2()
{
METHOD_PROLOGUE_EX_(CComponetObj, TmpObj1)
wprintf (L"ICom2Interface1->Function2 has been called.\r\n");
}

STDMETHODIMP_(ULONG) CComponetObj::XTmpObj2::AddRef()
{
METHOD_PROLOGUE_EX_(CComponetObj, TmpObj2)
return (ULONG)pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) CComponetObj::XTmpObj2::Release()
{
METHOD_PROLOGUE_EX_(CComponetObj, TmpObj2)
return (ULONG)pThis->ExternalRelease();
}

STDMETHODIMP CComponetObj::XTmpObj2::QueryInterface(REFIID iid, LPVOID * ppv)
{
METHOD_PROLOGUE_EX_(CComponetObj, TmpObj2)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppv);
}

STDMETHODIMP_(void) CComponetObj::XTmpObj2::Function1()
{
METHOD_PROLOGUE_EX_(CComponetObj, TmpObj2)
printf ("ICom2Interface2->Function1 has been called.\r\n");
}

STDMETHODIMP_(void) CComponetObj::XTmpObj2::Function2()
{
METHOD_PROLOGUE_EX_(CComponetObj, TmpObj2)
printf ("ICom2Interface2->Function2 has been called.\r\n");
}
...全文
242 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jimette 2013-03-05
  • 打赏
  • 举报
回复
悟迟 2013-02-22
  • 打赏
  • 举报
回复
引用 1 楼 hb19820102 的回复:
困扰了两天的问题,只因为错了几个字母. IMPLEMENT_DYNCREATE 宏被我写成了IMPLEMENT_DYNAMIC, 偏偏这个被写错的宏还有定义. 阴差阳错.
标记
oyljerry 2013-01-26
  • 打赏
  • 举报
回复
^_^,很多时候需要细心
  • 打赏
  • 举报
回复
困扰了两天的问题,只因为错了几个字母. IMPLEMENT_DYNCREATE 宏被我写成了IMPLEMENT_DYNAMIC, 偏偏这个被写错的宏还有定义. 阴差阳错.

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧