vc中调用Com组件的方法详解

2023-05-16

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

  #import  " 组件所在目录myCom.dll "  no_namespace 或
  #import 
" 类型库所在目录myCom.tlb "
  
using   namespace  MYCOM;
ContractedBlock.gif ExpandedBlockStart.gif 方式1
  CoInitialize(NULL);
  CLSID clsid;
  CLSIDFromProgID(OLESTR(
" myCom.GetRes " ),  //
                   & clsid);                 //
  CComPtr < IGetRes >  pGetRes;  //  智能指针
  pGetRes.CoCreateInstance(clsid);
  pGetRes
-> Hello();
  pGetRes.Release(); 
//  小心哦,请看最后的“注意”
  CoUninitialize();
ContractedBlock.gif ExpandedBlockStart.gif 方式2
 CoInitialize(NULL);
  CLSID clsid;
  HRESULT hr 
=  CLSIDFromProgID(OLESTR( " myCom.GetRes " ),
                               
& clsid);
  IGetRes 
* ptr  =  NULL;
  hr
= CoCreateInstance(clsid,
                      NULL,
                      CLSCTX_INPROC_SERVER,
                      __uuidof(IGetRes),
                      (LPVOID
* ) & ptr);
   ptr
-> Hello();
   CoUninitialize();
 
ContractedBlock.gif ExpandedBlockStart.gif 方式3
  CoInitialize(NULL);
   HRESULT hr;
   CLSID clsid;
   hr 
=  CLSIDFromProgID(OLESTR( " myCom.GetRes " ),
                        
& clsid);
   IGetRes
*  ptr  =  NULL;
   IGetResEx
*  ptrEx  =  NULL;
   
//  使用CoCreateClassObject创建一个组件(特别是mutilThreads)的多个对象的时候,效率更高.
   IClassFactory *  p_classfactory  =  NULL;
   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对用户的透明性),不推荐使用。
  ExpandedBlockStart.gif方式4

  //  定义一个函数指针类型
   typedef HRESULT (__stdcall  *  pfnHello)(REFCLSID,REFIID, void ** );
   pfnHello fnHello 
=  NULL;  //  创建一个函数指针变量
   
//  将COM组件DLL像一般DLL一样加载,得到DLL句柄
   HINSTANCE hdllInst  =  LoadLibrary( " *:\*.dll " );
   
//  判断DLL加载是否成功
    if  (NULL  !=  hdllInst)
   {
       
//  取得相应的函数地址
       fnHello  =  (pfnHello)GetProcAddress(hdllInst,
                                          
" DllGetClassObject " );
       
if  (NULL  !=  fnHello)
       {
            
//  得到类工厂接口指针
            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)  &&
                    (pGetRes 
!=  NULL))
                {
                   pGetRes
-> Hello();
                   pGetRes
-> Release();
                }
                pcf
-> Release();
            }
       }
       FreeLibrary(hdllInst);
   }
------------------------------------方式5 ------------------------------------
    通过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此时发生析构,导致了程序的崩溃,解决这个问题的另一个方法是:
ContractedBlock.gif ExpandedBlockStart.gif 代码
   CoInitialize(NULL);
   CLSID clsid;
   CLSIDFromProgID(OLESTR(
" myCom.GetRes " ),
                   
& clsid);
   CComPtr
< IGetRes >  pGetRes;  //  智能指针
   pGetRes.CoCreateInstance(clsid);
   pGetRes
-> Hello();
   
//  pGetRes.Release();  //  将其注释掉
   CoUninitialize();
--------------------------------------------------------------------
以上就是COM的5中方法,当然具体怎么使用还是要根据具体情况而定。

转载于:https://www.cnblogs.com/rogee/archive/2010/10/03/1841680.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • chrome浏览器提取网页视频

    http blog csdn net pipisorry article details 37728839 在我们平时上网看视频听音乐时都会产生缓存 xff0c 可是我们非常难通过一些软件把当中的视频和音乐文件提取出来 网页抓取视频的方法
  • js 统计一个字符串中,出现最多的字符和出现次数

    运用到的关键函数是str charAt index xff1a 根据位置返回字符 另外 xff0c 建立一个对象o xff0c 其中存放的key为字符串的各不重复的字母 xff0c 键值为出现的次数 代码 xff1a span class
  • IdentityServer4 配置负载均衡

    如果使用 IdentityServer4 做授权服务的负载均衡 xff0c 默认情况下是不可以的 xff0c 比如有两个授权服务站点 xff0c 一个资源服务绑定其中一个授权服务 xff08 Authority配置 xff09 xff0c
  • android 打开串口log,user版本如何打开uart,让android log从串口kernel log输出

    数据流控制是否正确 xff0c 一般需关闭 xff0c 下面为RS232的三种流控制模式介绍 xff1a DTR DSR xff1a 硬件上要有对应接口 xff0c 软件上实现对应协议 xff0c 才能实现此流控制 具体实现起来 xff0c
  • 安装flashplugin提示依赖libgdk-pixbuf2.0-0

    为什么80 的码农都做不了架构师 xff1f gt gt gt 今天安装flashplugin 出现问题 xff0c sudo apt get install adobe flashplugin 结果提示 xff1a 下列软件包有未满足的依
  • Python新手入门教程,从环境准备到掌握基本编程

    Lesson 1 准备好学习Python的环境 下载的地址是 xff1a www python org 为了咱们的便当 xff0c 我在校内作了copy xff1a http 10 1 204 2 tool compiler amp IDE
  • mariadb使用C语言编程,MHA实现mariadb的高可用的详细步骤及配置参数详解

    MHA实现mariadb的高可用的详细步骤及配置参数详解 A 实验环境说明 a 4台centos7主机 b 角色说明 xff1a a MHA xff1a 192 168 36 35 b Master mariadb xff1a 192 16
  • c语言中sizeof函数的作用是,c语言中sizeof函数的用法

    C语言sizeof函数如何使用 xff1f 怎样利用sizeofCSS布局HTML小编今天和大家分享各种数据类型占用的字节数 xff1f 1 sizeof不是函数 xff0c 它只是一个操作符 operator 2 sizeof的作用是返回
  • AutoCAD快捷键大全

    送给学习AutoCAD的朋友 xff0c 最后一张图片是可以打印的键盘标签 xff0c 可以打印出来贴在键盘上方便记住 xff01 如果感觉模糊的话 xff0c 可以单击文章图片进行查看 xff01
  • 如何恢复U盘里的删除文件?

    对于经常使用到U盘的用户来说 xff0c 误删U盘内重要数据的情况经常发生 xff0c U盘内重要的资料从电脑上被删除后 xff0c 不经过回收站 xff0c 我们很难从回收站中还原数据 那么 xff0c 如何恢复u盘删除文件 xff1f
  • maven maven.compiler.source和maven.compiler.target的坑

    最近建议产品组把jdk 1 7升级到1 8 xff0c 昨晚开发报了个问题过来 xff0c 说maven compiler source和maven compiler target改成1 8之后 xff0c 编译出来的代码还是1 7 xff
  • 1‘b0 什么意思

    在看datasheet 中有类似表达式如下 xff1a 3 39 b000 1 39 b1 1 39 b0 3 39 b000这个表示 xff1a b代表二進制 3代表位元數 1 39 b1 xff1a 宣告為一位元二進制之值為1 xff0
  • css 识别软件测出来的尺寸和代码设置的不一样

    这是我在模仿网页时遇到的问题 xff0c 困扰了一会儿 xff0c 情况是这样的 我下载了参考的网页html文件 xff0c 为了测量某个box的高度 xff0c 用了一款可以截图识别的软件 xff1a 量出来的box高度是30px xff
  • SpringBoot中注入ApplicationContext对象的三种方式

    在项目中 xff0c 我们可能需要手动获取spring中的bean对象 xff0c 这时就需要通过 ApplicationContext 去操作一波了 xff01 1 直接注入 xff08 Autowired xff09 span clas
  • vue中$attrs你会用吗?

    这篇文章的知识点是父子组件通讯 xff0c 如果你了解 props 但是还没了解过 attrs xff0c 那么建议你花1分钟时间阅读 xff0c 了解它的优点 xff0c 并学会在项目中使用 关于 attrs的介绍 包含了父作用域中不作为
  • 企业微信三方应用开发(二)授权开通及登录流程

    何谓企业微信第三方应用 一句话简介 一个S商场 企业微信 里入驻了D商站 xff08 服务商 xff09 在卖他的C产品 xff08 三方应用 xff09 三句话路径 我们申请成为企业微信服务商 xff0c 入驻到企业微信 然后经过 应用开
  • PHP+AJAX实现账号注册和登陆,附可用demo

    前言 登陆和注册已经是网站的标配了 xff0c 所以这是我们web开发学习过程中必学的了 其实很容易实现 xff0c 只需要懂数据库的增删改查 xff0c 还有if else的条件语句即可做出来 目录 css Login Reg css s
  • ftp服务器无法使用浏览器访问解决方法

    浏览器默认工作在被动模式 可能你的环境无法让ftp服务器工作在主动模式 这个很容易测试 你在IE浏览器的工具 internet选项 高级中取消使用被动ftp的设置 xff0c 看看浏览器是否还可以访问ftp服务器 xff0c 如果访问不了
  • Python抓取糗事百科成人版图片

    最近开始学习爬虫 xff0c 一开始看的是静觅 的爬虫系列文章 xff0c 今天看到糗事百科成人版 xff0c 心里就邪恶了一下 xff0c 把图片都爬下来吧 xff0c 哈哈 虽然后来实现了 xff0c 但还是存在一些问题 xff0c 暂
  • vc中调用Com组件的方法详解

    Requirement 1 创建myCom dll 该COM只有一个组件 两个接口IGetRes 方法Hello IGetResEx 方法HelloEx xff1b 2 在工程中导入组件或类型库 import 34 组件所在目录myCom