第一篇已经对COM结构思想有一定的了解,这篇做一个简单的实现DLL接口。关于一些DLL的导入导出和一些.lib的包含我这里就不说明了,具体的细节可以看这里:http://blog.csdn.net/u011599942/article/details/11195667
代码的实现部分如下:
接口头文件 IUnknowService.h
- #include<iostream>
- #include<string>
- using namespace std;
-
- #ifdef _EXPORTING
- #define CLASS_DECLSPEC __declspec(dllexport)
- #else
- #define CLASS_DECLSPEC __declspec(dllimport)
- #endif
-
- //IUnknowService 接口主要是为了查询这个组件里实现了哪些接口。
- //如果指定查询的接口不存在(可能目前使用的是这个组件的早期的版本),
- //那么返回值是NULL。
-
- class IUnknowService
- {
- public:
- virtual void QueryInterface(string type,void** ppv) = 0;
- virtual void Add() = 0;
- virtual void Release() = 0;
- };
-
- //接口的实现实际上也是一个中间层。实际提供下载服务的是其他一些类。
- class IPerson:public IUnknowService
- {
- public:
- virtual void Eat() = 0;
- };
- class IBook:public IUnknowService
- {
- public:
- virtual void Read() = 0;
- };
这边的IUnknowService与标准的IUnknow的定义不同,标准的是有返回值的,而且第一个参数是个ID。这里只是借用COM的思想来简单实现下。IPerson 和 IBook 是两个不同的接口类。可以这样理解,不同的接口类可以是不同时期发行的DLL库的不同版本,这样只要同时继承了这些版本的接口并可以实现版本的兼容。
接口实现类 InterFace.h
- #include"IUnknowService.h"
-
- class CTeacher:public IPerson,IBook
- {
- public:
- CTeacher():m_refCount(0){ }
- virtual void QueryInterface(string type,void** ppv);
- virtual void Add();
- virtual void Release();
- virtual void Eat();
- virtual void Read();
- int GetrefCount() { return m_refCount; }
- private:
- int m_refCount; //引用计数
- };
- void CTeacher::QueryInterface(string type,void** ppv)
- {
- if("Person" == type)
- *ppv = static_cast<IPerson*> (this);
- else if("Book" == type)
- *ppv = static_cast<IBook*>(this);
- if(*ppv)
- static_cast<IUnknowService*>(*ppv)->Add();
- }
- void CTeacher::Release()
- {
- m_refCount--;
- if(0 == m_refCount)
- {
- delete this;
- printf("Component destroy...\n");
- }
- else
- printf("引用计数为:%d \n",m_refCount);
- }
- void CTeacher::Add(){ m_refCount++; printf("引用计数为:%d \n",m_refCount); }
- void CTeacher::Eat(){ printf("Eatting!\n"); }
- void CTeacher::Read(){ printf("Reading!\n"); }
这个是接口的实现类,m_refCount用来保存引用计数。
DLL的导出:main.cpp
- #include"InterFace.h"
-
- extern"C" CLASS_DECLSPEC IUnknowService* Create();
-
- IUnknowService* Create()
- {
- IUnknowService* _interface = static_cast<IPerson*>(new CTeacher);
- _interface->Add();
- return _interface;
- }
在另一个工程中包含接口头文件 IUnknowService.cpp,包含对应生成的DLL和.lib
DLL的导入:main.cpp
- #include<iostream>
- #include"IUnknowService.h"
- using namespace std;
-
- #pragma comment(lib,"Com.lib")
- extern"C" CLASS_DECLSPEC IUnknowService* Create();
-
- void main()
- {
- IUnknowService *obj = Create();
- IPerson* person1 = NULL;
- IBook* book1 = NULL;
- obj->QueryInterface("Person",(void**)&person1);
- person1->Eat();
- obj->QueryInterface("Book",(void**)&book1);
- book1->Read();
- person1->Release();
- book1->Release();
- obj->Release();
- }
这里说明一下QueryInterface的第二个参数 void**ppv,我们调用QueryInterface("Person",(void**)&person1)是可知这里相当于ppv=&person1,也就是ppv指向了person1。因此*ppv就成了person,void**ppv成了 void *person。
好的,到此这个COM结构思想简单实现DLL接口已经结束了,下面是输出的结果:

|