刀与剑-C++ COM组件调用

写在最前

        接触com已经有一段时间了,奈何愚钝。只识得一点皮毛。对于新手不要说了解其中的原理,就连调用使用Com组件都困难。

正文开始

        本文将较为详细地介绍C++ Com接口从获取接口声明,初始化套间,创建对象实例介绍。

        一、获得接口声明

                在C++中任意函数的使用我们都必须得到头文件一样的东西,而com的一个很大的亮点就是不需要额外提供头文件,首先我们介绍几种获取方式。

                1、com提供者编译生成com组件的dll/exe时生成的_i.h 文件:

        com组件编译会生成_i.c、_i.h文件,该文件由IDL接口声明文件生成而来。使用com包含该_i.h文件即可,头文件中包含com组件的所有声明。

#include"../ATL Dll/ATLDll_i.h"

                 2、使用.tlb 文件生成:

        编译com组件生成EXE/DLL文件时,除了会生成_i.h和_i.c以外还会额外生成一个.tlb文件。而该文件可以使用#import 方式作为模块导入,之后直接编译,ms会为我们生成一个带有声明的头文件,使用重复1中过程即可。

         首先将tlb文件复制到我们需要使用的项目下,使用import包含,代码如下:

#include<atlcomcli.h>
//生成的tlh文件会自己加上namespace因此使用no_namesapce
//named_guids 指示编译器以旧样式定义和初始化 GUID 变量,格式为 LIBID_MyLib 、、 CLSID_MyCoClass IID_MyInterface 和 DIID_MyDispInterface 

#import "ATLDll.tlb" no_namespace

int _tmain(int argc, _TCHAR* argv[])
{

	return 0;
}

                之后直接编译生成一次项目,会在中间目录得到.tli和.tlh文件,同样包含tlh文件即可。

                 3、使用com组件的二进制dll/exe生成:

                        以上两种情况都需要由com组件的提供者提供除开二进制执行模块以外的文件,这当然是不够好的,因此com提供直接从二进制生成接口相关声明的特性。

                同2中方法,直接复制模块到你的项目目录下,并且使用import导入,之后直接生成一次。

#include <iostream>
#import "ATL Dll.dll" no_namespace

int main()
{

    return 0;
}

         生成后在中间目录得到组件的声明文件,同样包含tlh文件即可。

         二、创建com组件实例

                在一的介绍中我们得到了对com组件声明的头文件,此操作保证我们使用中不会报错。但不仅仅于此,我们使用com还需要保证该组件在系统注册,dll/exe/服务有不同的注册方法。

                注册保证我们的程序可以在系统的众多组件中找到我们指定的组件,该行为是在代码中使用com组价的前提。

               在注册com组件后,我们程序以uuid为唯一标识创建com组件实例,而uuid是com开发者编写时确定,uuid保证了其自身的唯一性,一定不会与别的组件撞车。

                创建时获取该ID的办法有两种:

                        ①直接使用"一"中生成的头文件声明中具有,直接使用,但需要使用__uuidof()关键字,其中uuid的名字来源于atl对象名,在头中声明如:

         使用也十分简单:

#import "ATL Dll.dll" no_namespace
#include"./x64/Debug/atl dll.tlh"
#include<atlcomcli.h>
#include<Windows.h>


int main()
{
    CoInitialize(NULL);

    //创建智能指针
    CComPtr<IDllATLSimpleObject1> p;

    //创建实例
    p.CoCreateInstance(__uuidof(DllATLSimpleObject1));

    p->xxx...//调用组件接口提供的方法
    
}

                        ②使用 ProgID 查找出uuid,该名字为组件接口的别名,可以用于查找,uuid使用如下:

#import "ATL Dll.dll" no_namespace
#include"./x64/Debug/atl dll.tlh"
#include<atlcomcli.h>
#include<Windows.h>


int main()
{
    CoInitialize(NULL);

    //创建智能指针
    CComPtr<IDllATLSimpleObject1> p;

    //定义存储uuid的变量
    CLSID clsid;

    //获取类的guid
    CLSIDFromProgID(L"DllATLSimpleObject1.ProgID", &clsid);

    //创建实例
    p.CoCreateInstance(clsid);


    p->xxx...//调用组件接口提供的方法
    
}

                该名字由com的开发者确定,且在上面的接口声明中不会出现,但我们可以在组件注册到系统后通过注册表查看其名字。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值