com组件接口_com组件特点

com组件接口_com组件特点int main( int argc, char *argv[] ){cout << "Ini

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

int 
main( 
int 
argc, 
char 
*argv[] )
{
   
cout << 
"Initializing COM" 
<< endl;
 
   
if 
( FAILED( CoInitialize( NULL )))
   
{
      
cout << 
"Unable to initialize COM" 
<< endl;
      
return 
-1;
   
}
 
   
ISampleMath* pSampleMath;
   
HRESULT 
hr;
   
// This time use CoCreateInstance
   
hr = CoCreateInstance( CLSID_SampleMath,
                          
NULL,
                          
CLSCTX_LOCAL_SERVER,
                          
IID_ISampleMath,
                          
(
void
**) &pSampleMath );
 
   
if 
( FAILED( hr ))
   
{
      
cout << 
"Failed to create server instance. HR = " 
<< hr << endl;
      
CoUninitialize();
      
return 
-1;
   
}
 
   
// Access the IMath interface
   
long 
lResult;
   
pSampleMath->Add( 134, 353, &lResult );
   
cout << 
"134 + 353 = " 
<< lResult << endl;
 
 
 
   
// Release all of our interfaces
   
if 
( pSampleMath )
 
   
CoUninitialize();
 
   
return 
0;
}
 
 

COM组件可以是一个Dll(进程内组件),也可以是一个EXE(进程外组件)。进程内组件就是组件和客户程序在同一进程内,进程外组件即组件和客户程序分别有自己的进程空间。

    一个COM组件可以包含多个COM对象,一个COM对象又可以有多个接口。

 

第2章 COM对象和接口

2.1 CLSID和IID

    对于COM对象来说,接口是它与外界进行交互的唯一途径。

    每个COM对象,可以用CLSID来标识,COM对象的每个接口可以用IID来标识。CLSID和IID都是128位的标识符GUID,是一个随机数,可以由两方面特性来保证:空间(如网络适配器地址)和时间。

    GUID可以通过COM库的API函数生成:

HRESULT CoCreateGuid( GUID * pguid );

2.1.2 COM对象和C++对象的不同
COM对象的数据成员封装以组建模块为最终边界,对于对象用户是完全透明的、不可见的,用户必须通过接口方法来访问数据成员;C++对象的封装特性只是语义上的,用户可以直接看到数据成员。
2.2 COM接口结构
COM组件开发知识重点——COM原理与应用篇(一)
接口是包含了一组函数的数据结构。客户程序利用这些函数获得组件对象的服务。接口成员函数中的字符串变量必须使用Unicode字符指针。
客户程序用一个指向接口数据结构的指针来调用接口成员函数,接口指针又指向pVtable(指向vtable的指针),pVtable指向一组函数,称为接口函数表(虚函数表vtable),表中每一项为4个字节长的函数指针,每个函数指针再指向函数的具体实现。
2.2.2 接口描述语言IDL
2.3 IUnknown接口
COM定义的每个接口都必须从IUnknown接口继承过来,因为IUnknown接口提供了两个重要特性:生存期控制和接口查询。

COM组件开发知识重点——COM原理与应用篇(一)

QueryInterface用于查询COM对象的其他接口指针,AddRef和Release用于对引用计数进行操作。

在COM对象级实现引用计数,精细度比较合适。

 

2.3.1 使用引用计数规则

(1)函数的参数中使用接口指针变量。

输入参数:在被调用函数中,不必调用AddRef和Release函数。

输出函数:在被调用函数返回之前,对输出参数调用AddRef,增加引用计数。

输入-输出参数:在参数被修改之前,对原来传进来的接口指针调用Release,引用计数减1,在参数被修改之后,对新的接口指针变量指针调用AddRef,若在函数执行过程中,参数没有被修改,则不必调用AddRef和Release函数。

(2)局部接口指针变量。

在局部函数块中,一个局部接口指针变量被赋了值并调用了接口成员函数,则对该局部接口指针变量
不必调用AddRef和Release函数。
(3)全局接口指针变量。
在把全局接口指针变量作为输入参数传给某个函数之前,调用AddRef,在函数返回之后调用Release。
(4)C++中类成员变量为接口指针变量:适用于(3)。
(5)在顺序执行过程中,如果对一个接口指针变量赋值,则对赋值后的接口指针变量调用AddRef,如果赋值前的接口指针变量还没有结束,则赋值前必须对它调用Release以便先结束它的使用。

COM的实现

3.1 进程内组件(DLL)的实现,可以参考DLL技术,主要参数为:

1)LoadLibrary:装载DLL模块

2)GetProcAddress:取引出函数的地址

3)FreeLibrary:释放DLL模块

    COM采用LPC(本地过程调用)和RPC(远程过程调用)的方法进行进程之间的通信,LPC用于在同一机器上的不同进程之间进行通信,而RPC用于在不同机器上的进程之间进行通信。

COM组件开发知识重点——COM原理与应用篇(二)3.2 组件程序的两个用于注册的入口函数为DllRegisterServer和DllUnregisterServer,注册组件使用命令:RegSvr32 *.dll;反注册组件使用命令:RegSvr32 /u *.dll,进程内组件注册使用此命令。进程外组件注册必须支持两个命令行参数/RegServer 和/UnregServer。
3.3 类厂

    COM库通过类厂创建COM对象,对应每一个COM类,都有一个类厂专门用于该COM类的对象创建工作。类厂本身也是一个COM对象,它支持接口IClassFactory。

COM组件开发知识重点——COM原理与应用篇(二)CreateInstance创建对应的COM对象,LockServer控制组件的生存周期。

类厂由函数DllGetClassObject创建。

COM组件开发知识重点——COM原理与应用篇(二)DllGetClassObject返回类厂对象的接口指针,再通过CreateInstance创建对应的COM对象。
3.3.2 COM库与类厂的交互

    创建对象函数:

1)若创建远程对象或希望一次获取对象的多个接口指针,选用CoCreateInstanceEx。

COM组件开发知识重点——COM原理与应用篇(二)

2)若希望获取类厂对象或要调用类厂的某些成员函数,选用CoGetClassObject,通常IID=IID_IclassFactory,进程内组件直接调用DLL的CoGetClassObject,若CoGetClassObject创建的类厂对象位于进程外组件,函数启动组件进程,然后等待,直到组件进程把它支持的COM类对象的类厂注册到COM中,返回类厂信息。

COM组件开发知识重点——COM原理与应用篇(二)

3)其他情况下,选用CoCreateInstance创建对象,CoCreateInstance封装类厂创建对象的过程,返回COM对象的接口指针,不能创建远程机器上的对象。

COM组件开发知识重点——COM原理与应用篇(二)COM组件开发知识重点——COM原理与应用篇(二)
3.4 COM库

    COM库初始化函数:CoInitialize

    COM库终止函数:CoUninitialize

3.4.2 COM库的内存管理

    COM提供的内存管理器标准,是一个COM接口IMalloc。当组件内存的分配和释放不在同一模块,需要用到内存管理器,COM库封装了三个API函数,用于内存分配和释放

CoTaskMemAlloc

CoTaskMemFree
CoTaskMemRealloc

3.4.3 组件程序的装载和卸载

1)进程内组件的装载、卸载

2)进程外组件的装载、卸载

    组件程序满足两个条件才可以被卸载:组件中对象数为0;类厂的锁计数器为0。此时,DllCanUnloadNow返回TRUE。

    在判断返回类型HRESULT时,需用宏SUCCEEDED和FAILED。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/167343.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • iec104规约遥测遥信解析笔记「建议收藏」

    iec104规约遥测遥信解析笔记「建议收藏」最近在写104规约的解析暂时做一个笔记,先写一个遥信的后期再补全规约解析表如下:104规约解析 启动字符 1字节 取值 68H APCI应用规约控制信息 APDU应用规约数据单元 …

    2022年6月20日
    82
  • stack overflow at line 9[通俗易懂]

    stack overflow at line 9[通俗易懂]web开发中,从设备得到一些信息显示在web页面中的文本框中,结果显示对话框1.起初认为可能是文本框的字符限制原因,有默认长度,故加上maxlength=128足够长,结果问题还是存在。2.因为这个问题在goole火狐 搜狗浏览器中都不存在,在IE6 360极速浏览器中存在,所以认为可能是浏览器的设置问题,从网上找了一下,解决办法是:打开IE的工具-Internet选项

    2022年7月15日
    26
  • Taiko taiko

    Taiko taikoTaikotaikoDescription拆拆超级喜欢太鼓达人(赛后大家可自行百度规则),玩久了也对积分规则产生了兴趣,理论上连击数越多,分数增加的越快,而且还配合着击打准确度有相应的计算规则,拆拆觉得这些规则太复杂了,于是把规则自行简化了下:对于一段击打序列,我们假设Y为打中,N为未打中(没有良可之分了)我们视连续的n次击中为n连击 相应的分数为1+2+3

    2025年8月23日
    3
  • linux安装卸载软件的命令_shell命令卸载软件

    linux安装卸载软件的命令_shell命令卸载软件linux卸载软件命令Linuxprovidesdifferentmethodsforinstallingsoftware.YoucaninstallsoftwarefromthestandardUbuntusoftwarerepositoriesusingtheUbuntuSoftwareCenter,fromoutsideofthestan…

    2025年10月17日
    2
  • 线性代数攻略(适合复习考试,零基础不挂科秘籍)「建议收藏」

    线性代数攻略(适合复习考试,零基础不挂科秘籍)「建议收藏」前言1、考试保过,最低在70分以上,零基础,只要看了复习攻略或者答题模板,一定能过。前提是真的认真看了,也练习了。2、多看,把这上面的例题多练,要不考试的时候会忘了哪个题用哪个方法。一定一定要牢记,多看,有的题不要问原因,直接记过程即可。3、要抽出至少两天的时间认真看这套答题模板,否则挂科了补考可真的是会浪费时间,线代这么简单,一定不要挂!4、出题的顺序会变,但是类型基本不会变,掌握做题技巧就行。5、如果是学知识,建议别看了,还是认真去看书,本攻略只适合高效率的让你不挂科,只是提高分数,

    2025年6月13日
    3
  • Unity之协程

    Unity之协程老早就对Unity这个功能产生了强烈的好奇,今天就要把这块骨头给啃了。目前我对协程的理解相当于有点像线程,但它实际上不是线程。话不多说先来个代码给个初印象:一、开启协程:我在Unity下创建了一个Cube(随便什么物体都行),然后把我的cs文件挂载上去。点击Unity上的开始按钮,运行:代码如下:usingSystem.Collections;usingSystem…

    2022年6月21日
    68

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号