转载自:http://www.cppblog.com/woaidongmao/archive/2011/01/10/138250.html

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

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

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

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

方法一:

[cpp] view plaincopyprint?
  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();
   CoInitialize(NULL);CLSID clsid;CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);CComPtr<IGetRes> pGetRes;//智能指针pGetRes.CoCreateInstance(clsid);pGetRes->Hello();pGetRes.Release();//小心哦!!请看最后的“注意”CoUninitialize();


方法二:

[cpp] view plaincopyprint?
  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();
   CoInitialize(NULL);CLSID clsid;HRESULT hr=CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);IGetRes *ptr;hr=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,__uuidof(IGetRes),(LPVOID*)&ptr);ptr->Hello();
clip_image001   CoUninitialize();

方法三:

[cpp] view plaincopyprint?
  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();
   CoInitialize(NULL);HRESULT hr;CLSID clsid;hr=CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);IGetRes* ptr;IGetResEx* ptrEx;//使用CoCreateClassObject创建一个组件(特别是mutilThreads)的多个对象的时候,效率更高.IClassFactory* p_classfactory;hr=CoGetClassObject(clsid,CLSCTX_INPROC_SERVER,NULL,IID_IClassFactory, (LPVOID*)&p_classfactory);p_classfactory->CreateInstance(NULL,__uuidof(IGetRes),(LPVOID*)&ptr);p_classfactory->CreateInstance(NULL,__uuidof(IGetResEx),(LPVOID*)&ptrEx);ptr->Hello();ptrEx->HelloEx();


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

[cpp] view plaincopyprint?
  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);
typedef HRESULT (__stdcall * pfnHello)(REFCLSID,REFIID,void**);
pfnHello fnHello= NULL;
HINSTANCE hdllInst = LoadLibrary("组件所在目录myCom.dll");
fnHello=(pfnHello)GetProcAddress(hdllInst,"DllGetClassObject");
if (fnHello != 0)
{IClassFactory* pcf = NULL;HRESULT hr=(fnHello)(CLSID_GetRes,IID_IClassFactory,(void**)&pcf);if (SUCCEEDED(hr) && (pcf != NULL)){IGetRes* pGetRes = NULL;hr = pcf->CreateInstance(NULL, IID_IFoo, (void**)&pGetRes);if (SUCCEEDED(hr)   && (pFoo != NULL)){pGetRes->Hello();pGetRes->Release();}pcf->Release();}
}
FreeLibrary(hdllInst);

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

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

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

[cpp] view plaincopyprint?
  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();
CoInitialize(NULL);
CLSID clsid;
CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
{CComPtr<IGetRes> pGetRes;//智能指针pGetRes.CoCreateInstance(clsid);pGetRes->Hello();
}
CoUninitialize();

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

c++中调用Com组件的方法详解相关推荐

  1. 来总结一下在VC中调用COM组件的方法

    来总结一下在VC中调用COM组件的方法(大家来补充) [问题点数:50分,结帖人_foo] http://bbs.csdn.net/topics/50319093 发表于: 2004-04-17 16 ...

  2. vue ajax highcharts,在vue项目中引入highcharts图表的方法(详解)

    npm进行highchars的导入,导入完成后就可以进行highchars的可视化组件开发了 npm install highcharts --save 1.components目录下新建一个char ...

  3. php中读取大文件实现方法详解

    php中读取大文件实现方法详解 来源:   时间:2013-09-05 19:27:01   阅读数:6186 分享到:0 [导读] 本文章来给各位同学介绍php中读取大文件实现方法详解吧,有需要了解 ...

  4. php调用C代码的方法详解和zend_parse_parameters函数详解

    来源:http://my.oschina.net/Customs/blog/490873 http://blog.csdn.net/super_ufo/article/details/3863731 ...

  5. c调用python脚本如何获取结果_使用C++调用Python代码的方法详解

    一.配置python环境问题 1.首先安装Python(版本无所谓),安装的时候选的添加python路径到环境变量中 安装之后的文件夹如下所示: 2.在VS中配置环境和库 右击项目->属性-&g ...

  6. python怎么横着输出_对python3中, print横向输出的方法详解

    对python3中, print横向输出的方法详解 Python 2 : print打印的时候,如果结尾有逗号,打出来时候不会换行.但是在python3里面就不行了. Python3: 3.0的pri ...

  7. Linux中history历史命令使用方法详解

    在/etc/profile里添加如下:#History export HISTTIMEFORMAT="[%F %T]" HISTDIR=/home/common/.hist if ...

  8. python支持向量机回归_Python中支持向量机SVM的使用方法详解

    除了在Matlab中使用PRTools工具箱中的svm算法,Python中一样可以使用支持向量机做分类.因为Python中的sklearn库也集成了SVM算法,本文的运行环境是Pycharm. 一.导 ...

  9. python更新数据库表的时间字段_python更新数据库中某个字段的数据(方法详解)

    连接数据库基本操作,我把每一步的操作是为什么给大家注释一下,老手自行快进. 请注意这是连接数据库操作,还不是更新. import pymysql #导包 #连接数据库 db = pymysql.con ...

最新文章

  1. 三十八、页面分配策略
  2. mysql解析运行时间_分析 MySQL 语句运行时间
  3. golang指针与c指针的异同
  4. Java黑皮书课后题第5章:5.6(英里与千米之间的互换)编写一个程序,并排显示下面两个表格
  5. Hadoop学习总结:Map-Reduce的过程解析
  6. 动态加载NT驱动(源码)
  7. java单链表 提供增删改查_java实现单链表增删改查的实例代码详解
  8. 一个JS多个数组取交集算法
  9. centos7 服务器安装nginx,mysql,php
  10. Yii 多表关联relations,需要与with()方法联合使用
  11. 【疫情模型】基于matlab改进SEIR模型【含Matlab源码 670期】
  12. 【信号检测】基于双稳随机共振微弱信号检测含Matlab源码
  13. 计算机出现测试模式,win10系统右下角显示测试模式内部版本10601的详细步骤
  14. Firefox 不知道如何打开此地址,因为协议 (javascrpit) 未和任何程序关联.
  15. 真香!红色警戒游戏源代码被开源了!
  16. html5游戏 遥控器按键,遥控器按键功能说明汇总
  17. 如何发好外贸邮件,看亚马逊SES邮件服务商怎么说?
  18. 公交线路管理 数据结构课程设计
  19. 圣朱妮佩洛|San Junipero(5)
  20. SAS9.4 安装注意事项

热门文章

  1. 虚拟机克隆改变IP地址,配置环境及免密设置
  2. 可以用计算机进行模拟实验,随着信息技术的发展,包括核实验在内的许多科学研究都可以用计算机进行模拟实验, - 问答库...
  3. html5新增的js api,对HTML5新增JS Api的思考
  4. python数据清理的实践总结_Python数据清洗实践
  5. c语言 读取一个文件 删除注释,C/C++ 源文件删除注释代码
  6. php中tags,php中strip_tags()函数的用法举例
  7. python数据库execute返回值_selenium+python自动化101-使用execute_script() 方法获取 JavaScript 返回值...
  8. ios 拍照上传到服务器_ios端浏览器拍照上传到服务器,图片被旋转90度 php 解决方案...
  9. mysql同步到另一台服务器_mysql两台服务器主从同步
  10. ttc error oracle,ORA-03137: TTC protocol internal error : [12333]错误一例