DLL介面的實現(COM結構思想)二
阿新 • • 發佈:2019-01-04
程式碼的實現部分如下:
介面標頭檔案 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介面已經結束了,下面是輸出的結果: