您的位置:首页 > 其它

WCE下创建MFC的COM对象及使用方法(一)

2012-03-20 10:51 176 查看
转载请标明是引用于 http://blog.csdn.net/chenyujing1234

平台:VS2005+MIPSSDK

例子代码:

http://www.rayfile.com/zh-cn/files/7020e9b8-7240-11e1-b9ea-0015c55db73d/

参考书本:

《EVC高级编程及其应用开发》

1、新建MFC DLL工程。

创建时,选择 自动,这样就会自动产生

DllCanUnloadNow PRIVATE

DllGetClassObject PRIVATE

DllRegisterServer PRIVATE

DllUnregisterServer PRIVATE

2、添加组件和接口定义.

//声明组件GUID {50AF86CD-AAF2-43B8-8802-483CFF78EF38}
//DEFINE_GUID(CLSID_TimeLogServer, 
//0x50AF86CD,0xAAF2,0x43B8,{0x88,0x02,0x48,0x3C,0xFF,0x78,0xEF,0x38};
static const IID CLSID_TimeLogServer = 
{0x50AF86CD,0xAAF2,0x43B8,{0x88,0x02,0x48,0x3C,0xFF,0x78,0xEF,0x38}};

// 声明接口GUID{E6A499D6-E5D2-42CE-8DBA-2BA217DC0470}
//DEFINE_GUID(IID_ITimeLog,
//0xE6A499D6,0xE5D2,0x42CE,{0x8D,0xBA,0x2B,0xA2,0x17,0xDC,0x04,0x70};
static const IID IID_ITimeLog = 
{0xE6A499D6,0xE5D2,0x42CE,{0x8D,0xBA,0x2B,0xA2,0x17,0xDC,0x04,0x70}};

//接口ITimeLog的声明
DECLARE_INTERFACE_(ITimeLog,IUnknown)
{
	STDMETHOD(OutputLog)(BSTR* varLogText)PURE;
};

以下有两个作用:一是定义组件和接口的GUID值(可通过guidgen.exe来产生。

二是使用DECLARE_INTERFACE_宏来声明接口。

该宏的第一个参数为接口名,第二个参数为该接口的基类.注:如果该接口没有基类,那么应该用宏DECLARE_INTERFACE

#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method

表方法OutputLog返回值为HRESULT.PURE,该解释为="0",也就是纯虚函数,当方法返回值不是HRESULT时,应该使用宏STDMETHOD_(返回值,函数名)

3、声明组件类CTimeLogSeriver并实现接口的嵌套类。

右击工程->添加类,新建类CTimeLogServer,基类为CCmdTarget,在生成的TimeLogServer.h中

添加以下宏

DECLARE_DYNCREATE(CTimeLogserver)

	//声明实现ITimelog接口的嵌套类
	BEGIN_INTERFACE_PART(TimeLog,ITimeLog)//自动声明IUnknown接口的三个方法
		STDMETHOD(OutputLog)(BSTR* varLogText);
	END_INTERFACE_PART(TimeLog)
	//声明接口映射
	DECLARE_INTERFACE_MAP()
	//声明类厂
	DECLARE_OLECREATE(CTimeLogserver)
protected:
 // Generated message map functions
 //{{AFX_MSG(CTimeLogServer)
 // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG
DECLARE_MESSAGE_MAP()

在类里做了三件事:

DECLARE_DYNCREATE(CTimeLogserver)->声明实现ITimelog接口的嵌套类->声明接口映射->声明类厂->消自映射

此时编译报以下错

1>正在链接...
1>   正在创建库 DbAu13xx (MIPSII)\Debug/MFC_com.lib 和对象 DbAu13xx (MIPSII)\Debug/MFC_com.exp
1>TimeLogserver.obj : error LNK2001: 无法解析的外部符号 "protected: virtual struct AFX_INTERFACEMAP const * __cdecl CTimeLogserver::GetInterfaceMap(void)const " (?GetInterfaceMap@CTimeLogserver@@MBAPBUAFX_INTERFACEMAP@@XZ)
1>TimeLogserver.obj : error LNK2001: 无法解析的外部符号 "public: virtual long __cdecl CTimeLogserver::XTimeLog::QueryInterface(struct _GUID const &,void * *)" (?QueryInterface@XTimeLog@CTimeLogserver@@UAAJABU_GUID@@PAPAX@Z)
1>TimeLogserver.obj : error LNK2001: 无法解析的外部符号 "public: virtual unsigned long __cdecl CTimeLogserver::XTimeLog::AddRef(void)" (?AddRef@XTimeLog@CTimeLogserver@@UAAKXZ)
1>TimeLogserver.obj : error LNK2001: 无法解析的外部符号 "public: virtual unsigned long __cdecl CTimeLogserver::XTimeLog::Release(void)" (?Release@XTimeLog@CTimeLogserver@@UAAKXZ)
1>TimeLogserver.obj : error LNK2001: 无法解析的外部符号 "public: virtual long __cdecl CTimeLogserver::XTimeLog::OutputLog(wchar_t * *)" (?OutputLog@XTimeLog@CTimeLogserver@@UAAJPAPA_W@Z)


先不管,这是因为纯虚函数没有实现的原因

4、实现类厂和接口映射

IMPLEMENT_DYNCREATE(CTimeLogserver, CCmdTarget)

//实现类厂
IMPLEMENT_OLECREATE(CTimeLogserver,"TimeLogserver",
					0x50AF86CD,0xAAF2,0x43B8,0x88,0x02,0x48,0x3C,0xFF,0x78,0xEF,0x38);
//映射接口到相应的嵌套类,把TimeLog映射到CTimeLogserver
BEGIN_INTERFACE_MAP(CTimeLogserver,CCmdTarget)
	INTERFACE_PART(CTimeLogserver,IID_ITimeLog,TimeLog)
END_INTERFACE_MAP()

5、实现XTimeLog类的IUnknow接口。

//为XTimeLog嵌套类实现IUnknown接口

//实现IUnknown接口的AddRef方法
STDMETHODIMP_(ULONG) 
CTimeLogserver::XTimeLog::AddRef()
{
	METHOD_PROLOGUE(CTimeLogserver,TimeLog)
		return pThis->ExternalAddRef();
}

//实现IUnknown接口的Release()方法
STDMETHODIMP_(ULONG)
CTimeLogserver::XTimeLog::Release()
{
	METHOD_PROLOGUE(CTimeLogserver,TimeLog)
		return pThis->ExternalRelease();
}

//实现IUnknown接口的QueryInterface方法
STDMETHODIMP
CTimeLogserver::XTimeLog::QueryInterface(REFIID riid,void**ppvObj)
{
	METHOD_PROLOGUE(CTimeLogserver,TimeLog)
		return pThis->ExternalQueryInterface(&riid,ppvObj);
}

IUnknown接口有三个最基本的方法AddRef Release QueryInterface.

虽然CCmdTartget类已经实现了IUnknow接口,但必须将嵌套类的IUnknown映射到CCmdTarget支持的IUnknow接口中。

METHOD_PROLOGUE宏的两个参数用于指定实现组件对象的类和实现接口的嵌套类

6、实现ITimeLog接口的OutputLog方法



CTimeLogserver::XTimeLog::OutputLog(BSTR* varLogText)
{
	METHOD_PROLOGUE(CTimeLogserver,TimeLog)
		if(pThis->m_logfile)
		{
			CTime TimeStamp = CTime::GetCurrentTime();

			CString NowTime;
			NowTime.Format(_T("%d年%d月%d日%d:%d %d"),TimeStamp.GetYear(),TimeStamp.GetMonth(),TimeStamp.GetDay(),
				TimeStamp.GetHour(),TimeStamp.GetMinute(),TimeStamp.GetSecond());

			CString LogText((LPCWSTR)*varLogText);
			fwprintf(pThis->m_logfile,L"\n%s\n%s\n%",NowTime,LogText);
			return NOERROR;
		}
		else
		{
			AfxMessageBox(L"没有日志文件!");
			return S_FALSE;
		}
}


7、在CMFC_ComApp类初始应用程序和退出应用程序方法里添加"增加全局引用计数"和"减少全局引用计数"

================================

最后在布署时会提示

1>------ 已启动部署: 项目: MFC_com, 配置: Debug DbAu13xx (MIPSII) ------

1>c:\documents and settings\administrator\桌面\mfc_com_server\dbau13xx (mipsii)\debug\MFC_com.dll

1>正在注册文件...

1>部署和/或注册失败,错误为: 0x8973190e。 写入文件“\Storage Card\MFC_com.dll”时出错。错误 0x8007007e: 找不到指定的模块。

1>

========== 生成: 0 已成功, 0 已失败, 1 最新, 0 已跳过 ==========

========== 部署: 0 已成功, 1 已失败, 0 已跳过 ==========

解决方法:

工程->常规->MFC的使用 改为 在静态中使用MFC
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: