需求:
1.创建myCom.dll,该COM只有一个组件,两个接口:
   IGetRes--方法Hello(),
   IGetResEx--方法HelloEx()

2.在工程中导入组件或类型库

 #import "组件所在目录myCom.dll" no_namespace

   #import "类型库所在目录myCom.tlb"
   using namespace MYCOM;

方法一:

  1. CoInitialize(NULL);
  2. CLSID clsid;
  3. CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
  4. CComPtr<IGetRes> pGetRes;//智能指针
  5. pGetRes.CoCreateInstance(clsid);
  6. pGetRes->Hello();
  7. pGetRes.Release();//小心哦!!请看最后的“注意”
  8. CoUninitialize();
  1. CoInitialize(NULL);
  2. CLSID clsid;
  3. CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
  4. CComPtr<IGetRes> pGetRes;//智能指针
  5. pGetRes.CoCreateInstance(clsid);
  6. pGetRes->Hello();
  7. pGetRes.Release();//小心哦!!请看最后的“注意”
  8. CoUninitialize();

方法二:

  1. CoInitialize(NULL);
  2. CLSID clsid;
  3. HRESULT hr=CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
  4. IGetRes *ptr;
  5. hr=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
  6. __uuidof(IGetRes),(LPVOID*)&ptr);
  7. ptr->Hello();
  8. p_image001   CoUninitialize();
  1. CoInitialize(NULL);
  2. CLSID clsid;
  3. HRESULT hr=CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
  4. IGetRes *ptr;
  5. hr=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
  6. __uuidof(IGetRes),(LPVOID*)&ptr);
  7. ptr->Hello();
  8. p_image001   CoUninitialize();

方法三:

  1. CoInitialize(NULL);
  2. HRESULT hr;
  3. CLSID clsid;
  4. hr=CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
  5. IGetRes* ptr;
  6. IGetResEx* ptrEx;
  7. //使用CoCreateClassObject创建一个组件(特别是mutilThreads)的多个对象的
  8. 时候,效率更高.
  9. IClassFactory* p_classfactory;
  10. hr=CoGetClassObject(clsid,CLSCTX_INPROC_SERVER,
  11. NULL,IID_IClassFactory,
  12. (LPVOID*)&p_classfactory);
  13. p_classfactory->CreateInstance(NULL,__uuidof(IGetRes),
  14. (LPVOID*)&ptr);
  15. p_classfactory->CreateInstance(NULL,__uuidof(IGetResEx),
  16. (LPVOID*)&ptrEx);
  17. ptr->Hello();
  18. ptrEx->HelloEx();
  1. CoInitialize(NULL);
  2. HRESULT hr;
  3. CLSID clsid;
  4. hr=CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
  5. IGetRes* ptr;
  6. IGetResEx* ptrEx;
  7. //使用CoCreateClassObject创建一个组件(特别是mutilThreads)的多个对象的
  8. 时候,效率更高.
  9. IClassFactory* p_classfactory;
  10. hr=CoGetClassObject(clsid,CLSCTX_INPROC_SERVER,
  11. NULL,IID_IClassFactory,
  12. (LPVOID*)&p_classfactory);
  13. p_classfactory->CreateInstance(NULL,__uuidof(IGetRes),
  14. (LPVOID*)&ptr);
  15. p_classfactory->CreateInstance(NULL,__uuidof(IGetResEx),
  16. (LPVOID*)&ptrEx);
  17. ptr->Hello();
  18. ptrEx->HelloEx();

方法四:
直接从dll中得到DllGetClassObject,接着生成类对象及类实例(这方法可以使组件不用在注册表里注册,这是最原始的方法,但这样做没什么意义,至少失去了COM对用户的透明性),不推荐使用.

  1. typedef HRESULT (__stdcall * pfnHello)(REFCLSID,REFIID,void**);
  2. pfnHello fnHello= NULL;
  3. HINSTANCE hdllInst = LoadLibrary("组件所在目录myCom.dll");
  4. fnHello=(pfnHello)GetProcAddress(hdllInst,"DllGetClassObject");
  5. if (fnHello != 0)
  6. {
  7. IClassFactory* pcf = NULL;
  8. HRESULT hr=(fnHello)(CLSID_GetRes,IID_IClassFactory,(void**)&pcf);
  9. if (SUCCEEDED(hr) && (pcf != NULL))
  10. {
  11. IGetRes* pGetRes = NULL;
  12. hr = pcf->CreateInstance(NULL, IID_IFoo, (void**)&pGetRes);
  13. if (SUCCEEDED(hr)   && (pFoo != NULL))
  14. {
  15. pGetRes->Hello();
  16. pGetRes->Release();
  17. }
  18. pcf->Release();
  19. }
  20. }
  21. FreeLibrary(hdllInst);
  1. typedef HRESULT (__stdcall * pfnHello)(REFCLSID,REFIID,void**);
  2. pfnHello fnHello= NULL;
  3. HINSTANCE hdllInst = LoadLibrary("组件所在目录myCom.dll");
  4. fnHello=(pfnHello)GetProcAddress(hdllInst,"DllGetClassObject");
  5. if (fnHello != 0)
  6. {
  7. IClassFactory* pcf = NULL;
  8. HRESULT hr=(fnHello)(CLSID_GetRes,IID_IClassFactory,(void**)&pcf);
  9. if (SUCCEEDED(hr) && (pcf != NULL))
  10. {
  11. IGetRes* pGetRes = NULL;
  12. hr = pcf->CreateInstance(NULL, IID_IFoo, (void**)&pGetRes);
  13. if (SUCCEEDED(hr)   && (pFoo != NULL))
  14. {
  15. pGetRes->Hello();
  16. pGetRes->Release();
  17. }
  18. pcf->Release();
  19. }
  20. }
  21. FreeLibrary(hdllInst);

方法五:
通过ClassWizard利用类型库生成包装类,不过前提是com组件的接口必须是派生自IDispatch,具体方法:
    调出添加类向导(.NET中),选择类型库中MFC类,打开,选择"文件",选择"myCom.dll"或"myCom.tlb",接下来会出来该myCom中的所有接口,选择你想生成的接口包装类后,向导会自动生成相应的.h文件.这样你就可以在你的MFC中像使用普通类那样使用组件了.(CreateDispatch("myCom.GetRes") 中的参数就是ProgID通过Clsid在注册表中可以查询的到)

  1. CoInitialize(NULL);
  2. CGetRes getRest;
  3. if (getRest.CreateDispatch("myCom.GetRes") != 0)
  4. {
  5. getRest.Hello();
  6. getRest.ReleaseDispatch();
  7. }
  8. CoUninitialize();
  1. CoInitialize(NULL);
  2. CGetRes getRest;
  3. if (getRest.CreateDispatch("myCom.GetRes") != 0)
  4. {
  5. getRest.Hello();
  6. getRest.ReleaseDispatch();
  7. }
  8. CoUninitialize();

注意:
COM中的智能指针实际上是重载了->的类,目的是为了简化引用记数,几不需要程序员显示的调用AddRef()和Release(),但是为什么我们在Method 1中pGetRes.Release(),问题在与,我们的智能指针pGetRes生命周期的结束是在CoUninitialize()之后,CoInitialize所开的套间在CoUninitialize()后已经被关闭,而pGetRes此时发生析构,导致了程序的崩溃,解决这个问题的另一个方法是

  1. CoInitialize(NULL);
  2. CLSID clsid;
  3. CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
  4. {
  5. CComPtr<IGetRes> pGetRes;//智能指针
  6. pGetRes.CoCreateInstance(clsid);
  7. pGetRes->Hello();
  8. }
  9. CoUninitialize();
  1. CoInitialize(NULL);
  2. CLSID clsid;
  3. CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
  4. {
  5. CComPtr<IGetRes> pGetRes;//智能指针
  6. pGetRes.CoCreateInstance(clsid);
  7. pGetRes->Hello();
  8. }
  9. CoUninitialize();

以上就是COM的5中方法,当然具体怎么使用还是在于程序的环境,加以琢磨....

C++调用Com的更多相关文章

  1. 黑马毕向东Java基础知识总结

    Java基础知识总结(超级经典) 转自:百度文库 黑马毕向东JAVA基础总结笔记    侵删! 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部 ...

  2. 《果壳中的C# C# 5.0 权威指南》 - 学习笔记

    <果壳中的C# C# 5.0 权威指南> ========== ========== ==========[作者] (美) Joseph Albahari (美) Ben Albahari ...

  3. JS调用Android、Ios原生控件

    在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...

  4. 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付

    前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...

  5. 操作系统篇-调用门与特权级(CPL、DPL和RPL)

    || 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在前两篇文章(<操作系统篇-浅谈实模式与保护模式>和<操作系统篇-分段机制与GDT|LDT>)中,我们提到 ...

  6. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  7. django server之间通过remote user 相互调用

    首先,场景是这样的:存在两个django web应用,并且两个应用存在一定的联系.某些情况下彼此需要获取对方的数据. 但是我们的应用肯经都会有对应的鉴权机制.不会让人家随随便便就访问的对吧.好比上车要 ...

  8. 调用AJAX做登陆和注册

    先建立一个页面来检测一下我们建立的用户名能不能用,看一下有没有已经存在的用户名吗 可以通过ajax提示一下 $("#uid").blur(function(){ //取用户名 va ...

  9. nodejs进阶(2)—函数模块调用

    函数调用 1. 文件内普通函数调用 创建一个js文件命名为2_callFunction.js,其中定义一个函数fun1,向返回对象输出了一段字符串“你好,我是fun1”. //------------ ...

  10. 【初学python】使用python调用monkey测试

    目前公司主要开发安卓平台的APP,平时测试经常需要使用monkey测试,所以尝试了下用python调用monkey,代码如下: import os apk = {'j': 'com.***.test1 ...

随机推荐

  1. 中国第二代身份证验证js代码

    以下这部分代码截取自盛大的某个网页.详细我就不给url了.以下是相应的js代码: iW = new Array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1); iSum ...

  2. 【C/C++多线程编程之五】pthread线程深入理解

    多线程编程之pthread线程深入理解       Pthread是 POSIX threads 的简称,是POSIX的线程标准.           前几篇博客已经能给你初步的多线程概念.在进一步学 ...

  3. ubuntu12.04通过Ganglia利用NVML模块进行GPU监控

    1.安装Ganglia,这里安装的是3.1*版本,因为监控GPU的模块只支持3.1*版本系列的 apt-get install ganglia* 2.下载并安装PyNVML和NVML模块,下载地址ht ...

  4. ExecuteNonQuery()的用法

    ExecuteNonQuery()的用法 下面我们将详细讲解如何在Page_Load()中对数据库的增加.删除.修改,最后我们再来总结一下ExecuteNonQuery(),ExecuteScalar ...

  5. CSU 1806 Toll 自适应simpson积分+最短路

    分析:根据这个题学了一发自适应simpson积分(原来积分还可以这么求),然后就是套模板了 学习自适应simpson积分:http://blog.csdn.net/greatwall1995/arti ...

  6. openstack horizon 学习(2) navigation、dashboard、panels

    本章的主要内容是如何用horizon的navigation结构添加一个应用的面板. Horizon中提供了两种为应用添加panel的方法,一种是通过Pluggable Settings的方式,另一种是 ...

  7. missing required source folder

    Eclipse 中XXX is missing required source folder 问题的解决 https://blog.csdn.net/itzhangdaopin/article/det ...

  8. Could not find modernizr-2.6.2 in any of the sources GitLab: API is not accessible

    Could not find modernizr-2.6.2 in any of the sources GitLab: API is not accessible bundle exec rake ...

  9. C#面向过程之局部变量、成员变量、变量作用域、可变参数

    局部变量与成员变量:  局部变量:定义在方法里面的变量就叫做局部变量:没有默认的初始值,使用变量之前必须给它赋值成员变量:定义在类下面的变量叫做成员变量:如果是数值类型默认初始值为0 如果是引用类型默 ...

  10. 分布式消息通信(ActiveMQ)

    分布式消息通信(ActiveMQ) 应用场景 异步通信 应用解耦 流量削峰 # ActiveMQ安装 下载 http://activemq.apache.org/ 压缩包上传到Linux系统 apac ...