VS2005 MFC 开发COM 遇到的有关问题,
VS2005 MFC 开发COM 遇到的问题,高手请进.
我用VS2005 生成一个MFC DLL(支持自动化).
添加一个继承自CCmdTarget的类, 然后使用MFC标准方法添加接口与类厂(代码如下).问题是在客户程序中用CoCreateInstance创建组件的时候总是返回E_OUTOFMEMORY(在调用前已初始化COM库). 我跟踪程序,发现类厂已经被创建,但类厂却没有创建组件. 由于是标准的类厂实现, 无法跟踪到MFC类厂的代码中. 所以很迷茫.
另外还有一个现象是, 用VC6.0生成一个扩展DLL项目,把这些代码原封不动拷入,编译生成组件. 客户程序就可以正常创建组件,并能正常调用接口.
还有就是我注意到VC6.0没有生成的IDL文件,而VS2005却自动维护一个IDL文件,这个IDL文件中只有组件描述, 没有接口描述, 我手动加上接口描述后, 可调用还是不成功.
1, 接口定义:
2, 组件定义:
组件的实现代码:
我用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);
}