vc中调用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;
   HRESULT hr=CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
   IGetRes *ptr;
   hr=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
                 __uuidof(IGetRes),(LPVOID*)&ptr);
   ptr->Hello();
   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();
   CoUninitialize();

方法四:
直接从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);

方法五:
通过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();

注意:
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();

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

vc中调用Com组件的方法详解的更多相关文章

  1. VC中调用COM组件的方法(转载)

    原文参考:http://hi.baidu.com/mingyueye/item/53ebecd44da76917d80e4449 总结一下在VC中调用COM组件的方法 准备及条件: COM服务器为进程 ...

  2. vc 中调用COM组件的方法

    需求:1.创建myCom.dll,该COM只有一个组件,两个接口:   IGetRes--方法Hello(),   IGetResEx--方法HelloEx() 2.在工程中导入组件或类型库  #im ...

  3. Delphi中TStringList类常用属性方法详解

    TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 先把要讨论的几个属性列出来: 1.CommaText 2.Delim ...

  4. Java中的equals和hashCode方法详解

    Java中的equals和hashCode方法详解  转自 https://www.cnblogs.com/crazylqy/category/655181.html 参考:http://blog.c ...

  5. Angular.js中处理页面闪烁的方法详解

    Angular.js中处理页面闪烁的方法详解 前言 大家在使用{{}}绑定数据的时候,页面加载会出现满屏尽是{{xxx}}的情况.数据还没响应,但页面已经渲染了.这是因为浏览器和angularjs渲染 ...

  6. 转:Java中的equals和hashCode方法详解

    转自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这 ...

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

    php调用C代码的方法详解 在php程序中需要用到C代码,应该是下面两种情况: 1 已有C代码,在php程序中想直接用 2 由于php的性能问题,需要用C来实现部分功能   针对第一种情况,最合适的方 ...

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

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

  9. python中验证码连通域分割的方法详解

    python中验证码连通域分割的方法详解 这篇文章主要给大家介绍了关于python中验证码连通域分割的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用python具有一定的参考学习价值,需 ...

随机推荐

  1. (五)backbone - DEMO - 通信录改造之使用requirejs

    DEMO介绍是 DEMO通信录的扩展,使用requirejs模块化整合 大体实现 • model文件 model/contact.js define(function (){ // user cont ...

  2. 3月26日html(七)window document

    ---恢复内容开始--- 1.Window.document对象 一.找到元素: docunment.getElementById("id"):根据id找,最多找一个:     v ...

  3. android手机获取手机号

    最近做到一个项目,需要获取手机号.项目中使用的手机卡为电信卡,那么就以此为例吧. 网上不符合需求的方法 Google了一下,网上的做法如下: //获取手机号码 TelephonyManager tm  ...

  4. EAT/IAT Hook

    标 题: EAT/IAT Hook 作 者: Y4ng 时 间: 2013-08-21 链 接: http://www.cnblogs.com/Y4ng/p/EAT_IAT_HOOK.html #in ...

  5. 直播 linux上的第一个c++程序

    这里用crt来直播吧: 登录到服务器上之后: 1.mkdir -p 建一个文件夹 2.ll 查看一下这个文件夹 3.cd 进入这个文件夹 4.vim 进行文本编辑 写完之后,按下esc中止输入模式,用 ...

  6. Windows平台的JDK安装(转)

    下载Java的开发包JDK JDK有好几个类型版本,我们只需要选择Java SE类型的版本就行了.进入网页:http://www.oracle.com/technetwork/java/javase/ ...

  7. 转:AM335x启动流程(BootRom->MLO->Uboot)

    http://blog.chinaunix.net/uid-28458801-id-3486399.html 参考文件: 1,AM335x ARM Cortex-A8 Microprocessors ...

  8. Codeforces 461B Appleman and Tree

    http://codeforces.com/problemset/problem/461/B 思路:dp,dp[i][0]代表这个联通块没有黑点的方案数,dp[i][1]代表有一个黑点的方案数 转移: ...

  9. Unity脚本的生命周期中几个重要的方法

    1.function Update () {} 正常更新,用于更新逻辑.此方法每帧都会由系统自动调用一次.2.function LateUpdate () {} 推迟更新,此方法在Update() 方 ...

  10. 【转】android service 之二(IntentService)

    原文网址:http://rainbow702.iteye.com/blog/1143286 不管是何种Service,它默认都是在应用程序的主线程(亦即UI线程)中运行的.所以,如果你的Service ...