第一篇已經(jīng)對(duì)COM結(jié)構(gòu)思想有一定的了解,這篇做一個(gè)簡(jiǎn)單的實(shí)現(xiàn)DLL接口。關(guān)于一些DLL的導(dǎo)入導(dǎo)出和一些.lib的包含我這里就不說明了,具體的細(xì)節(jié)可以看這里:http://blog.csdn.net/u011599942/article/details/11195667
代碼的實(shí)現(xiàn)部分如下:
接口頭文件 IUnknowService.h
- #include<iostream>
- #include<string>
- using namespace std;
-
- #ifdef _EXPORTING
- #define CLASS_DECLSPEC __declspec(dllexport)
- #else
- #define CLASS_DECLSPEC __declspec(dllimport)
- #endif
-
- //IUnknowService 接口主要是為了查詢這個(gè)組件里實(shí)現(xiàn)了哪些接口。
- //如果指定查詢的接口不存在(可能目前使用的是這個(gè)組件的早期的版本),
- //那么返回值是NULL。
-
- class IUnknowService
- {
- public:
- virtual void QueryInterface(string type,void** ppv) = 0;
- virtual void Add() = 0;
- virtual void Release() = 0;
- };
-
- //接口的實(shí)現(xiàn)實(shí)際上也是一個(gè)中間層。實(shí)際提供下載服務(wù)的是其他一些類。
- class IPerson:public IUnknowService
- {
- public:
- virtual void Eat() = 0;
- };
- class IBook:public IUnknowService
- {
- public:
- virtual void Read() = 0;
- };
這邊的IUnknowService與標(biāo)準(zhǔn)的IUnknow的定義不同,標(biāo)準(zhǔn)的是有返回值的,而且第一個(gè)參數(shù)是個(gè)ID。這里只是借用COM的思想來簡(jiǎn)單實(shí)現(xiàn)下。IPerson 和 IBook 是兩個(gè)不同的接口類??梢赃@樣理解,不同的接口類可以是不同時(shí)期發(fā)行的DLL庫的不同版本,這樣只要同時(shí)繼承了這些版本的接口并可以實(shí)現(xiàn)版本的兼容。
接口實(shí)現(xiàn)類 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; //引用計(jì)數(shù)
- };
- 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("引用計(jì)數(shù)為:%d \n",m_refCount);
- }
- void CTeacher::Add(){ m_refCount++; printf("引用計(jì)數(shù)為:%d \n",m_refCount); }
- void CTeacher::Eat(){ printf("Eatting!\n"); }
- void CTeacher::Read(){ printf("Reading!\n"); }
這個(gè)是接口的實(shí)現(xiàn)類,m_refCount用來保存引用計(jì)數(shù)。
DLL的導(dǎo)出:main.cpp
- #include"InterFace.h"
-
- extern"C" CLASS_DECLSPEC IUnknowService* Create();
-
- IUnknowService* Create()
- {
- IUnknowService* _interface = static_cast<IPerson*>(new CTeacher);
- _interface->Add();
- return _interface;
- }
在另一個(gè)工程中包含接口頭文件 IUnknowService.cpp,包含對(duì)應(yīng)生成的DLL和.lib
DLL的導(dǎo)入: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的第二個(gè)參數(shù) void**ppv,我們調(diào)用QueryInterface("Person",(void**)&person1)是可知這里相當(dāng)于ppv=&person1,也就是ppv指向了person1。因此*ppv就成了person,void**ppv成了 void *person。
好的,到此這個(gè)COM結(jié)構(gòu)思想簡(jiǎn)單實(shí)現(xiàn)DLL接口已經(jīng)結(jié)束了,下面是輸出的結(jié)果:

|