COM本质论学习笔记(一)IDL
IDL是Interface Definition Language的所寫,翻譯為接口定義語言。
1.該語言規(guī)定,必須顯式的為每個接口函數(shù)指定參數(shù)的目的,例如
HRESULT foo([in]long* Input, [out]long* Output, [in, out]long* InAndOut);
2.通常,函數(shù)的返回值為HRESULT,表示執(zhí)行的狀況,以便被其他語言所捕獲,例如Visual Basic等。HRESULT大體分為三個部分:
31|30 29|28 ... 16|15 ...0
成?|?保留?|?? 操作碼?|?信息碼
功
或
失
敗
第31位如果是0那么代表成功,否則代表失敗,這也是Win32 SDK的SUCCESSED宏判斷的依據(jù):
#define SUCCESSED(hr) (long(hr) >= 0)
#define FAILD(hr) (long(hr) < 0)
3.該返回值只提供了函數(shù)的執(zhí)行情況,函數(shù)可以另外提供返回值:
HRESULT foo([in]long* Input, [out]long* Output, [out, retval]long* InAndOut);
該函數(shù)在VB里看起來應該是這樣的(憑記憶,未驗證):
Public Declare Function foo(ByVal Input as Integer, ByRef Output as Integer) as Integer
如果在VB中調用該函數(shù)失敗了,那么不是通過返回值把錯誤碼返回,而是VB的解釋器觸發(fā)一個異常,你需要在VB里用On Error xxxx來進行錯誤處理。
4.聲明一個接口。接口的聲明是如下形式滴~
[object, uuid(00000000-0000-0000-0000-000000000000)]
interface IMyInterface : IBaseInterface
{
????enum?MyEnum
????{
????????ME_aa,
????????ME_bb,
????}
????typedef struct _ASTRUCT
????{
????????MyEnum?me;
????????long val;
????}
????HRESULT foo1([in]LONG* Input, [out, retval]RetVal);
}
[]中的部分是接口屬性,其中object代表這是一個com接口,后面的部分是全局唯一標識符(GUID),當用在com接口時,也叫做接口標識符(IID)。
接下來IMyInterface是接口名,IBaseInterface是基接口名
{}中則是接口體。
5.細說GUID\IID\CLSID
GUID是個128位的大數(shù),所以COM用一個結構體來表示GUID
typedef struct _GUID
{
????DWORD??Data1;
????WORD????Data2;
????WORD????Data3;
????BYTE????? Data4[8];
}GUID;
你看 (4+2+2+8)*8=128.
同時,還有如下定義:
typedef GUID IID;
typedef GUID CLSID;
所以說,IID,CLSID和GUID都是一種東東。
有時為了判斷2個GUID是否相等,那么用引用就會很高效,所以還有如下宏定義,以及==?和 !=操作符:
#define REFGUID?? const GUID&
#define REFIID????? const IID&
#define REFCLSID? const CLSID&
這個GUID/IID通常用VCSDK附帶的GUIDGEN.EXE來生成,理論上不會重復~
6.結構體與聯(lián)合體
在IDL中也可以聲明結構體和聯(lián)合體
typedef struct _TestStruct
{
????long a;
????short b;
}TESTSTRUCT;
struct TESTSTRUCT2
{
????long a;
????short b;
};
union VALUE
{
????[case(1)]long a;
????[case(2)]short b;
};
也可以在結構體或者函數(shù)中使用聯(lián)合:
struct TESTSTRUCT3
{
????short t;
????[switch_is(t)]union VALUE
????{
????????[case(1)]long a;
????????[case(2)]short b;
????};
};
HRESULT foo1([in, switch_is(t)]union VALUE* pu, [in]short t);
7.屬性
給接口添加屬性,可以使用戶感覺更良好:
[object, uuid(...)]
interface IPropertyInterface : IUnknown
{
????// 只讀
????[propget] HRESULT Age([out, retval]long* RetVal);
????// 讀寫
????[propput] HRESULT ID([in]long id);
????[propget] HRESULT ID([out, retval]long* id);
}
實現(xiàn)這樣的接口也比較容易,只需要在C++類對應的方法前加get_或者put_即可
class CPropertyInterface : public IPropertyInterface
{
????public:
????....
????HRESULT get_Age(long* RetVal);
????HRESULT get_ID(long* RetVal);
????HRESULT put_ID(long id);
}
轉載于:https://www.cnblogs.com/yoran/archive/2008/03/11/1099601.html
總結
以上是生活随笔為你收集整理的COM本质论学习笔记(一)IDL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NickLee.FortuneBase数
- 下一篇: iPhone SDK发布