IDL接口描述语言和COM接口COM组件
来源:互联网 发布:自学英语口语的软件 编辑:程序博客网 时间:2024/05/29 04:18
接口描述语言(Interface description language,缩写IDL)
c++写的接口,只能c++和c识别,为了接口的通用性,让所有的语言都通用的定义使用接口
引入IDL,使用IDL定义接口以后,用MIDL编译为c++可用的接口定义
接口描述语言 - IDL(Interface Definition Language )
1 IDL和MIDL
IDL - 定义接口的一种语言,与开发语言无关.
MIDL.EXE - 可以将IDL语言定义接口,
编译成C++语言的接口定义
2 IDL的基础
IDL接口定义方式:在项目中添加**.idl文件,在文件中:
1导入idl
import "XXXX.idl"
2定义属性
[
attribute
]
3定义接口
interface A : interface_base
{
}
编译后生成三个文件
**_h.h 接口头文件
**_i.cpp 接口GUID
**_p.cpp 远程调用相关,代理层
2.1 Import 导入IDL文件,相当于C++的
#include
2.2 使用"[]"定义区域,属性描述
关键字,描述接口GUID等信息
1) object - 后续是对象
2) uuid - 定义对象GUID
3) helpstring - 帮助信息
4) version - 版本
5) point_default - 后续对象
中指针的默认使用方式
比如: uniqune - 表示指针可以
为空,但是不能修改
2.3 对象定义
1) 父接口是IUnknown接口
2) 在对象内添加函数,函数定义必须
是返回 HRESULT.
HRESULT是32位整数,返回函数是否
执行成功,需要使用 SUCCESSED和
FAILED宏来判断返回值.
COM接口
按照COM规范定义的接口,即为COM接口
1 COM接口的规范
1.1 IUnknown接口的等价性 -判断两个接口相等,需要获取两个接口的IUnknown接口
判断IUnknown接口的地址是都相等。
1.2自反性
接口可以使用QueryInterface查询到自己
1.3 对称性
接口A可以查询到接口B,那么接口B也可以查询到接口A
1.4 传递性
接口A可以查询到接口B,接口B可以查询到接口C,那么接口A就可以查询到接口C
1.5 时间无关性
接口A在某个时间可以查询到接口B,那么在后续的任何时间中也可以查询到接口B
2 接口的编写
2.1 定义IDL(编译后生成3个文件)IDL文件项目属性有了 MIDL(将IDL定义的接口编译为c++语言)选项,其中Mktyplib compa...选项去掉,组件内部相关,不去掉IDL编译失败
*_i.c 接口ID定义
*_h.h 接口头文件
*_p.c 接口代理层实现
2.2 实现接口
自定义实现类继承接口类,并实现相关函数,注意引入相关头文件(接口头文件和GUID定义文件)
自定义实现类中实现相关函数时必须使用STDMETHOD(无返回值)STDMETHOD_(有返回值)声明函数,STDMETHODIMP STDMETHODIMP_实现函数
2.3 实现接口的导出
实现全局接口创建函数
定义def文件中导出接口创建函数
COM组件
1 COM接口和COM组件
COM接口 - 函数集合COM组件 -
从接口角度:COM组件是一个接口的集合
从C++语言看:COM组件是一个类或多个类
从编程看:COM组件是一段可以执行的代码
COM组件通过一个或多个COM接口展示自己的功能
---------
||----o IUnknown 接口
|组件|
||----o IMath 接口
||
---------
2 组件的实现
2.1 定义类实现组件的功能2.2 每个组件都具有一个GUID
一般宏定义为:CLSID_组件名称
2.3 在IDL中,定义组件
[
uuid(39B16755-783D-49B1-93E2-0FCA9F66CC2D)
]
coclass Math
{
interface IMath;
};
2.4 创建组件,并获取接口
创建时传入组件GUID,在查询接口时加入组件GUID的判断
IDL实现COM组件代码示例
math.idl
import "oaidl.idl";import "ocidl.idl";import "objidl.idl";[object,uuid(CFF0849D-61E2-4ED1-9DC9-0E43E2FBDE25)]interface IMath :IUnknown{HRESULT Add(long nAdd1, long nAdd2, long* pnAdd) = 0;HRESULT Sub(long nSub1, long nSub2, long* pnSub) = 0;};[uuid(39B16755-783D-49B1-93E2-0FCA9F66CC2D)]coclass Math{interface IMath;};
CimpMath.h
#pragma once#include "math_h.h"class ClmpMath:public IMath{public:ClmpMath();~ClmpMath();//IUnKnuwnpublic:STDMETHOD(QueryInterface)(REFIID iid, LPVOID* ppiObject);STDMETHOD_(ULONG, AddRef)();STDMETHOD_(ULONG, Release)();//IMathpublic:STDMETHOD(Add)(long nAdd1, long nAdd2, long* pnAdd);STDMETHOD(Sub)(long nSub1, long nSub2, long* pnSub);//public:LONG m_nRef;};
CimpMath.cpp
#include "stdafx.h"#include "ClmpMath.h"ClmpMath::ClmpMath(){m_nRef = 0;}ClmpMath::~ClmpMath(){}STDMETHODIMP ClmpMath::QueryInterface(REFIID iid, LPVOID* ppiObject){if (iid == IID_IUnknown){*ppiObject = static_cast<IUnknown*>(this);}else if (iid == IID_IMath){*ppiObject = static_cast<IMath*>(this);}else{*ppiObject = NULL;return E_NOINTERFACE;}AddRef();return S_OK;}STDMETHODIMP_(ULONG)ClmpMath:: AddRef(){InterlockedIncrement(&m_nRef);return m_nRef;}STDMETHODIMP_(ULONG)ClmpMath::Release(){InterlockedDecrement(&m_nRef);if (m_nRef == 0){delete this;}return m_nRef;}STDMETHODIMP ClmpMath::Add(long nAdd1, long nAdd2, long* pnAdd){if (pnAdd == NULL){return E_POINTER;}*pnAdd = nAdd1 + nAdd2;return S_OK;}STDMETHODIMP ClmpMath::Sub(long nSub1, long nSub2, long* pnSub){if (pnSub == NULL){return E_POINTER;}*pnSub = nSub1 + nSub2;return S_OK;}
组件创建函数
IUnknown* CreateInstanceEx(CLSID clsid){//判断组件的CLSIDif (clsid == CLSID_Math){//创建对象ClmpMath* pMath = new ClmpMath;//获取接口IUnknown* piUnknown = NULL;pMath->QueryInterface(IID_IUnknown,(LPVOID*)&piUnknown);//返回接口return NULL;}return FALSE;}
0 0
- IDL接口描述语言和COM接口COM组件
- [COM]接口描述语言IDL
- [COM]接口描述语言IDL
- 接口定义语言IDL,COM
- COM组件编程—接口定义语言IDL
- [Windows]接口描述语言IDL
- com组件和多接口
- 组件基础和COM接口
- 分布式 COM - 代理/存根及 IDL 接口定义语言
- COM中的IDL语言的难点之接口指针
- 关于Com接口IDL的说明
- COM组件的接口和对象
- COM接口 C语言
- 创建COM组件以及COM接口流程
- (com组件)普通接口实例
- COM 组件接口的 IUnKnown 接口介绍
- COM对象和接口
- COM 对象 和 接口
- C++ 学习之路(1):拷贝构造函数
- 二进制整数的倒序
- 打开整个系统的隐藏文件
- 快乐的JYY
- HDOJ 3555 Bomb
- IDL接口描述语言和COM接口COM组件
- play 部署问题 play.exceptions.TemplateExecutionException: No signature of method: java.lang.String.f
- C++ 学习之路(2):对象数组和指针
- 阿里一面准备工作<java部分>
- Python——域名解析成IP地址
- 积分图(用于计算块像素差异的快速方法)
- [bzoj3676][APIO2014]回文串
- C++ 学习之路(3):向函数传递对象
- 猜拳游戏案例