// 完整的COM例子

#include <unknwn.h>
#include <iostream.h>
#include <objbase.h>

void Trace (const char* msg)
{
 cout << msg << endl;
}

/*注意这里为了实现多态都接口都使用了虚函数*/
/*使用_stdcall支持DLL调用*/
// interface
interface IX : IUnknown
{
 virtual void _stdcall Fx() = 0; 
};

interface IY : IUnknown
{
 virtual void _stdcall Fy() = 0; 
};

interface IZ : IUnknown
{
 virtual void _stdcall Fz() = 0; 
};

// Forward references for GUIDs
extern const IID IDD_IX;
extern const IID IDD_IY;
extern const IID IDD_IZ;

// component
class CA : public IX,
     public IY
{
/*从接口继承而来的都应该是虚函数,由于基类已经声明了virtual关键字,这里可以省略*/
public:
 // IUnknown
 HRESULT _stdcall QueryInterface (const IID& iid, void ** ppv);
 ULONG _stdcall AddRef (void)
 {
  return 0;
 }

ULONG _stdcall Release(void)
 {
  return 0;
 }
 
 // IX
 void _stdcall Fx()
 {
  cout << "Fx" << endl;
 }

// IY
 void _stdcall Fy()
 {
  cout << "Fy" << endl;
 }

};

// GUID
// {6134635D-4669-4c4b-BEB3-9223591AE918}
static const GUID IID_IX =
{ 0x6134635d, 0x4669, 0x4c4b, { 0xbe, 0xb3, 0x92, 0x23, 0x59, 0x1a, 0xe9, 0x18 } };
// {D90FD541-D995-4303-9A07-1CC54C6BA576}
static const GUID IID_IY =
{ 0xd90fd541, 0xd995, 0x4303, { 0x9a, 0x7, 0x1c, 0xc5, 0x4c, 0x6b, 0xa5, 0x76 } };
// {F881374D-98D7-48a2-AA72-373A988AF3D9}
static const GUID IID_IZ =
{ 0xf881374d, 0x98d7, 0x48a2, { 0xaa, 0x72, 0x37, 0x3a, 0x98, 0x8a, 0xf3, 0xd9 } };

HRESULT _stdcall CA::QueryInterface(const IID& iid, void ** ppv)
{
 if(IID_IUnknown == iid) 
 {
  Trace("QueryInterface: return pointer to IUnknow.");
//  *ppv = static_cast<IUnknown* > (this);  IUnknown是一个虚类不能产生实例
  *ppv = static_cast<IX* > (this);
 }
 else if(IID_IX == iid)
 {
  Trace("QueryInterface: return pointer to IX.");
  *ppv = static_cast<IX* > (this);
 }
 else if(IID_IY == iid)
 {
  Trace("QueryInterface: return pointer to IY.");
  *ppv = static_cast<IY* > (this);
 }
 else
 {
  Trace("QueryInterface: no interface.");
  *ppv = NULL;
  return E_NOINTERFACE;
 }
 // reinterpret_cast操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换
 reinterpret_cast<IUnknown* > (*ppv)->AddRef();   // 疑问
 
 return S_OK;
}

// Creation function
IUnknown * CreateInstance()
{
 IUnknown * pI = static_cast<IX*>(new CA);
 pI->AddRef();
 return pI;
}

int main()
{
 HRESULT hr;

// 方式一
 Trace("Client: Get an IUnKnow pointer");
 IUnknown * pIUnknown = CreateInstance();
 Trace("Client: Get interface IX");
 
// 方式二
 // 获取IX
 IX * pIX = NULL;
 hr = pIUnknown->QueryInterface(IID_IX, (void**)&pIX);
 if(SUCCEEDED(hr))
 {
  Trace("Client: Succeeded getting IX");
  pIX->Fx();  // Use interface IX
 }
 else
 {
  Trace("Client: Could not get interface IX");
 }

// 获取IY
 IY * pIY = NULL;
 hr = pIUnknown->QueryInterface(IID_IY, (void**)&pIY);
 if(SUCCEEDED(hr))
 {
  Trace("Client: Succeeded getting IY");
  pIY->Fy();  // Use interface IY
 }
 else
 {
  Trace("Client: Could not get interface IY");
 }

Trace("Client: ask for an unsupported interface");
 IZ * pIZ = NULL;
 hr = pIUnknown->QueryInterface(IID_IZ, (void**)&pIZ);
 if(SUCCEEDED(hr))
 {
  Trace("Client: Succeeded getting IZ");
  pIX->Fx();  // Use interface IX
 }
 else
 {
  Trace("Client: Could not get interface IZ");
 }

Trace("Client: Get interface IY from interface IX");
 IY * pIYfromIX = NULL;
 hr = pIX->QueryInterface(IID_IY, (void**)&pIYfromIX);
 if(SUCCEEDED(hr))
 {
  Trace("Client: Succeeded getting IY");
  pIYfromIX->Fy();
 }

IUnknown * pIUnknownFromIY = NULL;
 hr = pIY->QueryInterface(IID_IUnknown, (void**)&pIUnknownFromIY);
 if(SUCCEEDED(hr))
 {
  cout << "are the IUnknown pointers equal ?" << endl;
  if(pIUnknownFromIY == pIUnknown)
  {
   cout << "yes,pIUnknownFromIY == pIUnknown" << endl;
  }
  else
  {
   cout << "no,pIUnknownFromIY != pIUnknown" << endl;
  }
 }

delete pIUnknown;
}

// 完整的COM例子相关推荐

  1. MySQL笔记12:C语言访问MYSQL数据库的完整的代码例子

    C语言访问MYSQL数据库的完整的代码例子 1.手写安装带mysql sdk 的mysql 2.新建控制台项目,项目属性中把 C:\Program Files\MySQL\MySQL Server 5 ...

  2. 一个完整的AjaxPro例子

    一个完整的AjaxPro例子 源码下载 1.配置文件设置: <httpHandlers> <add verb="*" path="*.ashx" ...

  3. Django模板语言-1:一个完整的数据获取例子

    一.Django表单(form)请求: 打开的时候默认是GET请求,获取form表单的内容. 点提交的时候是POST请求,提交form表单的内容. 根据以上区别来编写获取表单内容: from djan ...

  4. C语言访问MYSQL数据库的完整的代码例子

    1.手写安装带mysql sdk 的mysql 2.新建控制台项目,项目属性中把 C:\Program Files\MySQL\MySQL Server 5.5\include 加入"包含目 ...

  5. 阿里云HaaS100物联网开发板学习笔记(六)做个智能灯---一个完整的开发例子

    摘要:本篇文章将前期几个专题综合起来,基于阿里云HaaS100的新固件设计制作一个智能灯.这个智能灯由云平台.手机APP端和设备端组成,基本上涵盖了一个物联网小项目所需的主要步骤. 目录 1.在阿里云 ...

  6. 官方完整HL7 ECG-XML例子及注释翻译(1)

    编者:李国帅 qq:9611153 微信lgs9611153 时间:2019-7-4 背景: 存储心电图数据的格式有很多种,比如HL7,Dicom,EDF,GDF等,其中HL7最是简单,直观,使用Xm ...

  7. Rest-Assured完整的测试例子

    参考资料:  使用 Rest-Assured 测试 REST API  使用 REST-Assured 测试 REST API 的进阶技巧和最佳实践 1.准备 eclipse.jdk.maven 新建 ...

  8. Java--微信支付--小程序支付--v3版--完整的代码例子

    微信官方文档–小程序支付:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml 微信官方文档–支付接入前准备https:// ...

  9. 【Python入门可视化】:22个完整数据可视化小例子,带你玩转可视化~

    总共22个完整的pyecharts例子,包含常用的配置方法,每个小例子都包含完整代码,为避免混淆,每个例子都差不多只包含单一配置的代码,更多有趣的源码分享可以在评论区回复. 1. 柱状图堆叠 不同系列 ...

最新文章

  1. 坚持写博客给我带来了什么
  2. HTML(WEB)开发day01
  3. mysql报错无效默认值1067_Mysql 报错:#1067 - Invalid default value for 'update_time
  4. 机器学习是什么--周志华
  5. [MySQL] INFORMATION_SCHEMA 数据库包含所有表的字段
  6. Linux(12)-命令行的使用,shell脚本
  7. (一)KitJs瀑布流组件特点
  8. 软考信息安全工程师学习笔记三(1.3 信息安全管理基础)
  9. 计算机二级考试改错题技巧
  10. Java服务器多站点,java客户端web服务器连接到多个web服务器
  11. mysql导出_mysql数据库导入导出
  12. 第二章 人工智能专题之Python进阶 - Matplotlib库
  13. R 语言详细安装教程(保姆级)及 RStudio简易安装教程
  14. HackTheBox –Craft实战
  15. PowerJob使用
  16. cnn 句向量_快速理解句向量模型,深度好文,一定要看
  17. scanf(%*s)
  18. 使用WG-8010 GPRS通讯模块
  19. 搜索引擎友好的HTML
  20. alipay本地jar安装

热门文章

  1. RDP 协议组件 X.224 在协议流中发现一个错误并且中断了客户端连
  2. Linux-2 文件管理(vi 和vim)
  3. -------Python中ConfigArgParse模块介绍---------
  4. easypoi导入excel
  5. CSS:text-decoration文本装饰
  6. 基于angularjs的单页面实例_基于AngularJs的单页面程序
  7. 站长问答:百度突然不收录了怎么办?
  8. 布尔教育php视频下载,布尔教育2016视频:PHP留言板制作教程
  9. python程序员教你用微信给对方定位!你说回家!却还在外面鬼混?
  10. oeacle报错:ORA-01122、ORA-01110、ORA-01207