轉(zhuǎn)自:http://kuaixingdong.blog.hexun.com/29627840_d.html
我們先看看COM所支持的一些類型的基本類:
(微軟提供,在comdef.h中定義)
在COM中使用的標準類Class如下所示:
_bstr_t:對BSTR類型進行打包,并提供有用的操作和方法;
_com_error:定義拋出的error對象;
_com_ptr_t:封裝COM接口指針
_variant_t:對VARIANT類型進行打包,并提供有用的操作和方法;
一、_variant_t類的簡單介紹:
_variant_t對象封裝了VARIANT數(shù)據(jù)類型。
The class manages resource allocation and deallocation and makes function calls to VariantInit and VariantClear as appropriate.
(1) _variant類提供的方法:
1> 構(gòu)造函數(shù)
_variant_t
對_variant_t變量初始化調(diào)用的是_variant_t的構(gòu)造函數(shù)。我們一般習(xí)慣于用一個int型的變量對數(shù)字類的變量進行初始化,這對_variant_t變量是不允許的。
原因很簡單,_variant_t 的構(gòu)造函數(shù)中沒有用整型( Int )對其初始化的構(gòu)造函數(shù)
可先將整型轉(zhuǎn)化成long,然后再對其進行初始化
2> Attach()
Attaches a VARIANT object into the _variant_t object.
3> Clear()
Clears the encapsulated VARIANT object.
4> ChangeType
Changes the type of the _variant_t object to the indicated VARTYPE.
5> Detach
Detaches the encapsulated VARIANT object from this _variant_t object.
6> SetString
將一個string賦值給_variant_t對象;
7> Operators
賦值操作,給現(xiàn)有的_variant_t對象賦一個新值;
8> operator ==, !=
對比兩個 _variant_t 對象是否相等;
9> Extractors
Extract data from the encapsulated VARIANT object.
(2) _variant_t的定義:
_variant_t類封閉了VARIANT數(shù)據(jù)類型,VARIANT是一個結(jié)構(gòu)體類型,我們可以看一下它的定義
- typedef struct tagVARIANT
- {
- VARTYPE vt; //存儲數(shù)據(jù)類型
- unsigned short wReserved1;
- unsigned short wReserved2;
- unsigned short wReserved3;
- union
- {
- Byte bVal; // VT_UI1.
- Short iVal; // VT_I2.
- long lVal; // VT_I4.
- float fltVal; // VT_R4.
- double dblVal; // VT_R8.
- VARIANT_BOOL boolVal; // VT_BOOL.
- SCODE scode; // VT_ERROR.
- CY cyVal; // VT_CY.
- DATE date; // VT_DATE.
- BSTR bstrVal; // VT_BSTR.
- DECIMAL FAR* pdecVal // VT_BYREF|VT_DECIMAL.
- IUnknown FAR* punkVal; // VT_UNKNOWN.
- IDispatch FAR* pdispVal; // VT_DISPATCH.
- SAFEARRAY FAR* parray; // VT_ARRAY|*.
- Byte FAR* pbVal; // VT_BYREF|VT_UI1.
- short FAR* piVal; // VT_BYREF|VT_I2.
- long FAR* plVal; // VT_BYREF|VT_I4.
- float FAR* pfltVal; // VT_BYREF|VT_R4.
- double FAR* pdblVal; // VT_BYREF|VT_R8.
- VARIANT_BOOL FAR* pboolVal; // VT_BYREF|VT_BOOL.
- SCODE FAR* pscode; // VT_BYREF|VT_ERROR.
- CY FAR* pcyVal; // VT_BYREF|VT_CY.
- DATE FAR* pdate; // VT_BYREF|VT_DATE.
- BSTR FAR* pbstrVal; // VT_BYREF|VT_BSTR.
- IUnknown FAR* FAR* ppunkVal; // VT_BYREF|VT_UNKNOWN.
- IDispatch FAR* FAR* ppdispVal; // VT_BYREF|VT_DISPATCH.
- SAFEARRAY FAR* FAR* pparray; // VT_ARRAY|*.
- VARIANT FAR* pvarVal; // VT_BYREF|VT_VARIANT.
- void FAR* byref; // Generic ByRef.
- char cVal; // VT_I1.
- unsigned short uiVal; // VT_UI2.
- unsigned long ulVal; // VT_UI4.
- int intVal; // VT_INT.
- unsigned int uintVal; // VT_UINT.
- char FAR * pcVal; // VT_BYREF|VT_I1.
- unsigned short FAR * puiVal; // VT_BYREF|VT_UI2.
- unsigned long FAR * pulVal; // VT_BYREF|VT_UI4.
- int FAR * pintVal; // VT_BYREF|VT_INT.
- unsigned int FAR * puintVal; //VT_BYREF|VT_UINT.
- };
- };
注意:vt用來存儲內(nèi)部變量(聯(lián)合體中保存的變量)的類型,聯(lián)合體用來存儲對應(yīng)類型的值
二、數(shù)據(jù)類型轉(zhuǎn)換
_bstr_t類可以作為_variant_t類與基本數(shù)據(jù)類型轉(zhuǎn)換的中介
(1) _variant_t與CString之間的轉(zhuǎn)化
1> CString轉(zhuǎn)換為_variant_t:
- CString str;
- _variant_t str1=(LPCTSTR)str;
使用_variant_t的成員函數(shù)SetString來對_variant_t的對象賦值會更好;
2> _variant_t轉(zhuǎn)換為CString:
- _variant_t vt;
- CString tempstr=(LPCSTR)_bstr_t(vt); //_bstr_t的構(gòu)造函數(shù)有對_variant_t類型的處理
(2) _variant_t與char *之間的轉(zhuǎn)換
1> char * 轉(zhuǎn)換為_variant_t
方法與CString轉(zhuǎn)換為_variant_t的方法類似:
- char * cValue;
- _variant_t vValue=(LPSTR)cValue;
2> _variant_t轉(zhuǎn)換為char *:
錯誤方法:
- _variant_t vValue;
- char * value=(LPSTR)(LPCSTR)_bstr_t(vValue)
value指向一堆亂碼...
原因:不能用char *直接指向(LPSTR)(LPCSTR)_bstr_t( _variant_t ),因為這樣轉(zhuǎn)換之后實際上是一個string,而非一個char *
正確方法:
進行轉(zhuǎn)換時,只能用strcpy(),將LPSTR指向的字符復(fù)制到char * 所指向的內(nèi)存中;
如下例:
- _variant_t vValue;
- char cValue[16]={0};
- strcpy(cValue, (LPCSTR)_bstr_t(vValue));
(3) 判斷_variant_t的值類型
下面的轉(zhuǎn)換代碼根據(jù)_variant_t的vt進行類型判斷,然后將數(shù)據(jù)值轉(zhuǎn)換為CString類型(可作為轉(zhuǎn)換為其他數(shù)據(jù)類型的中介)
- CString str;
-
- //以下代碼演示如何轉(zhuǎn)換為C標準字符串型
- switch(var.vt)
- {
- case VT_BSTR:
- {
- str=var.bstrVal;
- break;
- }
- case VT_I2: //var is short int type
- {
- str.Format("%d",(int)var.iVal);
- break;
- }
- case VT_I4: //var is long int type
- {
- str.Format("%d", var.lVal);
- break;
- }
- case VT_R4: //var is float type
- {
- str.Format("%10.6f", (double)var.fltVal);
- break;
- }
- case VT_R8: //var is double type
- {
- str.Format("%10.6f", var.dblVal);
- break;
- }
- case VT_CY: //var is CY type
- {
- str=COleCurrency(var).Format();
- break;
- }
- case VT_DATE: //var is DATE type
- {
- str=COleDateTime(var).Format();
- break;
- }
- case VT_BOOL: //var is VARIANT_BOOL
- {
- str= (var.boolVal==0) ?"FALSE": "TRUE";
- break;
- }
- default:
- {
- str.Format("Unk type %d\n",var.vt);
- TRACE("Unknown type %d\n",var.vt);
- break;
- }
- }