c++中调用Com组件的方法详解
转载自: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;
方法一:
- CoInitialize(NULL);
- CLSID clsid;
- CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
- CComPtr<IGetRes> pGetRes;//智能指针
- pGetRes.CoCreateInstance(clsid);
- pGetRes->Hello();
- pGetRes.Release();//小心哦!!请看最后的“注意”
- CoUninitialize();
CoInitialize(NULL);CLSID clsid;CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);CComPtr<IGetRes> pGetRes;//智能指针pGetRes.CoCreateInstance(clsid);pGetRes->Hello();pGetRes.Release();//小心哦!!请看最后的“注意”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();
- 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();
方法三:
- 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();
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对用户的透明性),不推荐使用.
- 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);
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在注册表中可以查询的到)
- CoInitialize(NULL);
- CGetRes getRest;
- if (getRest.CreateDispatch("myCom.GetRes") != 0)
- {
- getRest.Hello();
- getRest.ReleaseDispatch();
- }
- 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此时发生析构,导致了程序的崩溃,解决这个问题的另一个方法是
- CoInitialize(NULL);
- CLSID clsid;
- CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
- {
- CComPtr<IGetRes> pGetRes;//智能指针
- pGetRes.CoCreateInstance(clsid);
- pGetRes->Hello();
- }
- CoUninitialize();
CoInitialize(NULL);
CLSID clsid;
CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
{CComPtr<IGetRes> pGetRes;//智能指针pGetRes.CoCreateInstance(clsid);pGetRes->Hello();
}
CoUninitialize();
以上就是COM的5中方法,当然具体怎么使用还是在于程序的环境,加以琢磨....
c++中调用Com组件的方法详解相关推荐
- 来总结一下在VC中调用COM组件的方法
来总结一下在VC中调用COM组件的方法(大家来补充) [问题点数:50分,结帖人_foo] http://bbs.csdn.net/topics/50319093 发表于: 2004-04-17 16 ...
- vue ajax highcharts,在vue项目中引入highcharts图表的方法(详解)
npm进行highchars的导入,导入完成后就可以进行highchars的可视化组件开发了 npm install highcharts --save 1.components目录下新建一个char ...
- php中读取大文件实现方法详解
php中读取大文件实现方法详解 来源: 时间:2013-09-05 19:27:01 阅读数:6186 分享到:0 [导读] 本文章来给各位同学介绍php中读取大文件实现方法详解吧,有需要了解 ...
- php调用C代码的方法详解和zend_parse_parameters函数详解
来源:http://my.oschina.net/Customs/blog/490873 http://blog.csdn.net/super_ufo/article/details/3863731 ...
- c调用python脚本如何获取结果_使用C++调用Python代码的方法详解
一.配置python环境问题 1.首先安装Python(版本无所谓),安装的时候选的添加python路径到环境变量中 安装之后的文件夹如下所示: 2.在VS中配置环境和库 右击项目->属性-&g ...
- python怎么横着输出_对python3中, print横向输出的方法详解
对python3中, print横向输出的方法详解 Python 2 : print打印的时候,如果结尾有逗号,打出来时候不会换行.但是在python3里面就不行了. Python3: 3.0的pri ...
- Linux中history历史命令使用方法详解
在/etc/profile里添加如下:#History export HISTTIMEFORMAT="[%F %T]" HISTDIR=/home/common/.hist if ...
- python支持向量机回归_Python中支持向量机SVM的使用方法详解
除了在Matlab中使用PRTools工具箱中的svm算法,Python中一样可以使用支持向量机做分类.因为Python中的sklearn库也集成了SVM算法,本文的运行环境是Pycharm. 一.导 ...
- python更新数据库表的时间字段_python更新数据库中某个字段的数据(方法详解)
连接数据库基本操作,我把每一步的操作是为什么给大家注释一下,老手自行快进. 请注意这是连接数据库操作,还不是更新. import pymysql #导包 #连接数据库 db = pymysql.con ...
最新文章
- 三十八、页面分配策略
- mysql解析运行时间_分析 MySQL 语句运行时间
- golang指针与c指针的异同
- Java黑皮书课后题第5章:5.6(英里与千米之间的互换)编写一个程序,并排显示下面两个表格
- Hadoop学习总结:Map-Reduce的过程解析
- 动态加载NT驱动(源码)
- java单链表 提供增删改查_java实现单链表增删改查的实例代码详解
- 一个JS多个数组取交集算法
- centos7 服务器安装nginx,mysql,php
- Yii 多表关联relations,需要与with()方法联合使用
- 【疫情模型】基于matlab改进SEIR模型【含Matlab源码 670期】
- 【信号检测】基于双稳随机共振微弱信号检测含Matlab源码
- 计算机出现测试模式,win10系统右下角显示测试模式内部版本10601的详细步骤
- Firefox 不知道如何打开此地址,因为协议 (javascrpit) 未和任何程序关联.
- 真香!红色警戒游戏源代码被开源了!
- html5游戏 遥控器按键,遥控器按键功能说明汇总
- 如何发好外贸邮件,看亚马逊SES邮件服务商怎么说?
- 公交线路管理 数据结构课程设计
- 圣朱妮佩洛|San Junipero(5)
- SAS9.4 安装注意事项
热门文章
- 虚拟机克隆改变IP地址,配置环境及免密设置
- 可以用计算机进行模拟实验,随着信息技术的发展,包括核实验在内的许多科学研究都可以用计算机进行模拟实验, - 问答库...
- html5新增的js api,对HTML5新增JS Api的思考
- python数据清理的实践总结_Python数据清洗实践
- c语言 读取一个文件 删除注释,C/C++ 源文件删除注释代码
- php中tags,php中strip_tags()函数的用法举例
- python数据库execute返回值_selenium+python自动化101-使用execute_script() 方法获取 JavaScript 返回值...
- ios 拍照上传到服务器_ios端浏览器拍照上传到服务器,图片被旋转90度 php 解决方案...
- mysql同步到另一台服务器_mysql两台服务器主从同步
- ttc error oracle,ORA-03137: TTC protocol internal error : [12333]错误一例