打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
DLL接口的实现(COM结构思想)二
userphoto

2017.09.25

关注

第一篇已经对COM结构思想有一定的了解,这篇做一个简单的实现DLL接口。关于一些DLL的导入导出和一些.lib的包含我这里就不说明了,具体的细节可以看这里:http://blog.csdn.net/u011599942/article/details/11195667

代码的实现部分如下:

接口头文件 IUnknowService.h

  1. #include<iostream>  
  2. #include<string>  
  3. using namespace std;  
  4.   
  5. #ifdef _EXPORTING  
  6. #define CLASS_DECLSPEC __declspec(dllexport)  
  7. #else  
  8. #define CLASS_DECLSPEC __declspec(dllimport)  
  9. #endif  
  10.   
  11. //IUnknowService 接口主要是为了查询这个组件里实现了哪些接口。  
  12. //如果指定查询的接口不存在(可能目前使用的是这个组件的早期的版本),  
  13. //那么返回值是NULL。  
  14.   
  15. class IUnknowService  
  16. {  
  17. public:  
  18.     virtual void QueryInterface(string type,void** ppv) = 0;  
  19.     virtual void  Add() = 0;  
  20.     virtual void  Release() = 0;  
  21. };  
  22.   
  23. //接口的实现实际上也是一个中间层。实际提供下载服务的是其他一些类。  
  24. class IPerson:public IUnknowService  
  25. {  
  26. public:  
  27.     virtual void Eat() = 0;  
  28. };  
  29. class IBook:public IUnknowService  
  30. {  
  31. public:  
  32.     virtual void Read() = 0;  
  33. };  


这边的IUnknowService与标准的IUnknow的定义不同,标准的是有返回值的,而且第一个参数是个ID。这里只是借用COM的思想来简单实现下。IPerson 和 IBook 是两个不同的接口类。可以这样理解,不同的接口类可以是不同时期发行的DLL库的不同版本,这样只要同时继承了这些版本的接口并可以实现版本的兼容。

接口实现类 InterFace.h

  1. #include"IUnknowService.h"  
  2.   
  3. class CTeacher:public IPerson,IBook  
  4. {  
  5. public:  
  6.     CTeacher():m_refCount(0){   }  
  7.     virtual void QueryInterface(string type,void** ppv);  
  8.     virtual void Add();  
  9.     virtual void Release();  
  10.     virtual void Eat();  
  11.     virtual void Read();  
  12.     int GetrefCount() { return m_refCount; }  
  13. private:  
  14.     int m_refCount;  //引用计数  
  15. };  
  16. void CTeacher::QueryInterface(string type,void** ppv)  
  17. {  
  18.     if("Person" == type)  
  19.         *ppv = static_cast<IPerson*> (this);  
  20.     else if("Book" == type)  
  21.         *ppv = static_cast<IBook*>(this);  
  22.     if(*ppv)  
  23.         static_cast<IUnknowService*>(*ppv)->Add();  
  24. }  
  25. void CTeacher::Release()  
  26. {  
  27.     m_refCount--;  
  28.     if(0 == m_refCount)  
  29.     {  
  30.         delete this;  
  31.         printf("Component destroy...\n");  
  32.     }  
  33.     else  
  34.         printf("引用计数为:%d \n",m_refCount);  
  35. }  
  36. void CTeacher::Add(){   m_refCount++; printf("引用计数为:%d \n",m_refCount); }  
  37. void CTeacher::Eat(){   printf("Eatting!\n"); }  
  38. void CTeacher::Read(){  printf("Reading!\n"); }  

这个是接口的实现类,m_refCount用来保存引用计数。

DLL的导出:main.cpp

  1. #include"InterFace.h"  
  2.   
  3. extern"C" CLASS_DECLSPEC IUnknowService* Create();  
  4.   
  5. IUnknowService* Create()  
  6. {  
  7.     IUnknowService* _interface = static_cast<IPerson*>(new CTeacher);  
  8.     _interface->Add();  
  9.     return _interface;  
  10. }  


在另一个工程中包含接口头文件 IUnknowService.cpp,包含对应生成的DLL和.lib

DLL的导入:main.cpp

  1. #include<iostream>  
  2. #include"IUnknowService.h"  
  3. using namespace std;  
  4.   
  5. #pragma comment(lib,"Com.lib")  
  6. extern"C" CLASS_DECLSPEC IUnknowService* Create();  
  7.   
  8. void main()  
  9. {  
  10.     IUnknowService *obj = Create();  
  11.     IPerson* person1 = NULL;  
  12.     IBook*   book1 = NULL;  
  13.     obj->QueryInterface("Person",(void**)&person1);  
  14.     person1->Eat();  
  15.     obj->QueryInterface("Book",(void**)&book1);  
  16.     book1->Read();  
  17.     person1->Release();  
  18.     book1->Release();  
  19.     obj->Release();  
  20. }  

这里说明一下QueryInterface的第二个参数 void**ppv,我们调用QueryInterface("Person",(void**)&person1)是可知这里相当于ppv=&person1,也就是ppv指向了person1。因此*ppv就成了person,void**ppv成了 void *person。

好的,到此这个COM结构思想简单实现DLL接口已经结束了,下面是输出的结果:

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
蒋国纲 COM入门第二部分
InterlockedDecrement用法注意的事项
C++ 编程COM编程(一)
COM技术初探
COM技术初探(三)
Open Firmware API
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服