博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WCE下创建MFC的COM对象及使用方法(一)
阅读量:2398 次
发布时间:2019-05-10

本文共 4927 字,大约阅读时间需要 16 分钟。

 

转载请标明是引用于

平台:VS2005+MIPSSDK

 例子代码:

 

参考书本:

《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.exp1>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映射到CTimeLogserverBEGIN_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方法STDMETHODIMPCTimeLogserver::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

你可能感兴趣的文章
布隆过滤器过时了,未来属于布谷鸟过滤器?
查看>>
面试题 —— 数字幻方
查看>>
5折抢购最后一天 | 戴尔顶级配置电脑,限时秒!
查看>>
SpringBoot 究竟是如何跑起来的?
查看>>
阿里开源限流组件 Sentinel 集群流控全解析
查看>>
深度解密HTTP通信细节
查看>>
日活亿级用户的服务器架构要怎么搭?
查看>>
MySQL 是怎样运行的:从根儿上理解 MySQL
查看>>
开源搜索技术的核心引擎 —— Lucene
查看>>
码洞技术文章大全
查看>>
RPC 服务器之【多进程描述符传递】高阶模型
查看>>
程序员年龄增大后的职业出路是什么?
查看>>
快学 Go 语言 第 1 课 —— Hello World
查看>>
《快学 Go 语言》第 4 课 —— 低调的数组
查看>>
作为程序员,你是如何在工作以后找到女朋友的?
查看>>
一种简单的Failover机制
查看>>
Channel最佳实践之基本规则【译】
查看>>
天下无难试之HTTP协议面试刁难大全
查看>>
深入Python多进程编程基础
查看>>
深入理解RPC——RPC在企业服务中的核心价值
查看>>