C++调用Com
需求:
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();
- p_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的更多相关文章
- 黑马毕向东Java基础知识总结
Java基础知识总结(超级经典) 转自:百度文库 黑马毕向东JAVA基础总结笔记 侵删! 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部 ...
- 《果壳中的C# C# 5.0 权威指南》 - 学习笔记
<果壳中的C# C# 5.0 权威指南> ========== ========== ==========[作者] (美) Joseph Albahari (美) Ben Albahari ...
- JS调用Android、Ios原生控件
在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...
- 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付
前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...
- 操作系统篇-调用门与特权级(CPL、DPL和RPL)
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在前两篇文章(<操作系统篇-浅谈实模式与保护模式>和<操作系统篇-分段机制与GDT|LDT>)中,我们提到 ...
- 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)
一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...
- django server之间通过remote user 相互调用
首先,场景是这样的:存在两个django web应用,并且两个应用存在一定的联系.某些情况下彼此需要获取对方的数据. 但是我们的应用肯经都会有对应的鉴权机制.不会让人家随随便便就访问的对吧.好比上车要 ...
- 调用AJAX做登陆和注册
先建立一个页面来检测一下我们建立的用户名能不能用,看一下有没有已经存在的用户名吗 可以通过ajax提示一下 $("#uid").blur(function(){ //取用户名 va ...
- nodejs进阶(2)—函数模块调用
函数调用 1. 文件内普通函数调用 创建一个js文件命名为2_callFunction.js,其中定义一个函数fun1,向返回对象输出了一段字符串“你好,我是fun1”. //------------ ...
- 【初学python】使用python调用monkey测试
目前公司主要开发安卓平台的APP,平时测试经常需要使用monkey测试,所以尝试了下用python调用monkey,代码如下: import os apk = {'j': 'com.***.test1 ...
随机推荐
- distcp导致个别datanode节点数据存储严重不均衡分析
hadoop2.4生产集群已经执行一段时间了.因为大量的hadoop1.0上面的应用不断迁移过来.刚開始事hdfs这边还没有出现多少问题.随着时间的推移,近期发现个别的datanode节点上面的磁盘空 ...
- Skype for Business七大新功能
Lync Server 2013的下一版本号.Skype for Business将于2015年4月正式公布,下面是七大新功能. "呼叫监听"(Call Monitor)--假设你 ...
- POJ 3342 Party at Hali-Bula (树形dp 树的最大独立集 判多解 好题)
Party at Hali-Bula Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5660 Accepted: 202 ...
- windows server 证书的颁发与IIS证书的使用 Dapper入门使用,代替你的DbSQLhelper Asp.Net MVC中Action跳转(转载)
windows server 证书的颁发与IIS证书的使用 最近工作业务要是用服务器证书验证,在这里记录下一. 1.添加服务器角色 [证书服务] 2.一路下一步直到证书服务安装完成; 3.选择圈选 ...
- influxDB+telefraf+grafana
此贴自己记录 下载grafana https://grafana.com/grafana/download?platform=windows 从官网下载influxDB\telefraf的方法 : h ...
- Linux 系统内核空间与用户空间通信的实现与分析
本文转载自:https://www.ibm.com/developerworks/cn/linux/l-netlink/index.html 多数的 Linux 内核态程序都需要和用户空间的进程交换数 ...
- TFLearn 在给定模型精度时候提前终止训练
拿来主义:看我的代码,我是在模型acc和验证数据集val_acc都达到99.8%时候才终止训练. import numpy as np import tflearn from tflearn.laye ...
- bzoj 4883 棋盘上的守卫 —— 基环树转化
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4883 首先,注意到每个点可横可竖,但花费一样: 所以考虑行列的交集,那么这个条件可以转化为行 ...
- swift中使用GCDMulticastDelegate
在开源库XMPPFramework中提供了一个GCDMulticastDelegate类,使用它可以为一个对象添加多个被委托的对象,以前用oc编写的工程引入了这个类,使用起来十分方便.最近由于换了工作 ...
- P2476 [SCOI2008]着色方案
传送门 数学太珂怕了--膜一下->这里 记\(sum[i]\)为题中\(c[i]\)的前缀和,\(C[i][j]\)表示\(C_{i}^j\) 设\(f[i][j]\)表示前面\(i\)中颜色已 ...