SAFEARRAY、COleSafeArray、VARTYPE

VARIANT and VARIANTARG

是一個結構體。結構體中vt變量指明這個結構體封裝的哪種類型。結構體重包含了一個Union。該聯合體根據vt的類型不同而不同。比如:vt爲VT_UI1代表聯合體是unsigned char.

COleVariant

該類封裝了VARIANT結構體。在OLE automation中使用。這個類是從VARIANT結構體派生的。所以在需要VARIANT類型做參數的地方使用COleVariant類型都可以。而且VARIANT結構體的數據成員是COleVariant類的可獲取的數據成員。

SAFEARRAY

  SAFEARRAY的主要目的是用於automation中的數組型參數的傳遞。因爲在網絡環境中,數組是不能直接傳遞的,而必須將其包裝成SafeArray。實質上SafeArray就是將通常的數組增加一個描述符,說明其維數、長度、邊界、元 素類型等信息。SafeArray也並不單獨使用,而是將其再包裝到VARIANT類型的變量中,然後才作爲參數傳送出去。在VARIANT的vt成員的 值如果包含VT_ARRAY|...,那麼它所封裝的就是一個SafeArray,它的parray成員即是指向SafeArray的指針。 SafeArray中元素的類型可以是VARIANT能封裝的任何類型,包括VARIANT類型本身。

  使用SafeArray的具體步驟:

  方法一:

  包裝一個SafeArray:

  (1). 定義變量,如:

  VARIANT varChunk;

  SAFEARRAY *psa;

  SAFEARRAYBOUND rgsabound[1];

  (2). 創建SafeArray描述符:

  uIsRead=f.Read(bVal,ChunkSize);//read array from a file.

  if(uIsRead==0)break;

  rgsabound[0].cElements =uIsRead;

  rgsabound[0].lLbound = 0;

  psa = SafeArrayCreate(VT_UI1,1,rgsabound);

  (3). 放置數據元素到SafeArray:

  for(long index=0;index<uIsRead;index++)

  {

  if(FAILED(SafeArrayPutElement(psa,&index,&bVal)))

  ::MessageBox(NULL,"出毛病了。","提示",MB_OK | MB_ICONWARNING);

  }

  一個一個地放,挺麻煩的。

  (4). 封裝到VARIANT內:

  varChunk.vt = VT_ARRAY|VT_UI1;

  varChunk.parray = psa;

  這樣就可以將varChunk作爲參數傳送出去了。

  讀取SafeArray中的數據的步驟:

  (1). 用SafeArrayGetElement一個一個地讀

  BYTE buf[lIsRead];

  for(long index=0;index<lIsRead;index++)

  {

  ::SafeArrayGetElement(varChunk.parray,&index,buf+index);

  }

  就讀到緩衝區buf裏了。

  方法二:

  使用SafeArrayAccessData直接讀寫SafeArray的緩衝區:

  (1). 讀緩衝區:

  BYTE *buf;

  SafeArrayAccessData(varChunk.parray, (void **)&buf);

  f.Write(buf,lIsRead);

  SafeArrayUnaccessData(varChunk.parray);

  (2). 寫緩衝區:

  BYTE *buf;

  ::SafeArrayAccessData(psa, (void **)&buf);

  for(long index=0;index<uIsRead;index++)

  {

  buf=bVal;

  }

  ::SafeArrayUnaccessData(psa);

  varChunk.vt = VT_ARRAY|VT_UI1;

  varChunk.parray = psa;

  這種方法讀寫SafeArray都可以,它直接操縱SafeArray的數據緩衝區,比用SafeArrayGetElement和 SafeArrayPutElement速度快。特別適合於讀取數據。但用完之後不要忘了調用::SafeArrayUnaccessData (psa),否則會出錯的。

  如果SafeArray中存的是BSTR的二維數組,則代碼如下:

  if(varChunk.vt = VT_ARRAY | VT_BSTR)

  {

  BSTR* buf;

  long LBound; // 數組下界

  long UBound; // 數組上界

  SafeArrayAccessData(varChunk.parray, (void **)&buf);

  SafeArrayGetLBound(varChunk.parray, 1, &LBound);

  SafeArrayGetUBound(varChunk.parray, 1, &UBound);

  for(long i = LBound; i < UBound; i ++)

  {

  CString str(buf);

  MessageBox(str);

  }

  SafeArrayUnaccessData(varChunk.parray);

 

  }

------------------------------------------------------------------------------------------------------------------------------

COleSafeArray

COleSafeArray類是用於處理任意類型和維數的數組的類。COleSafeArray是從OLE VARIANT結構派生而來的。OLE SAFEARRAY成員函數在可以通過COleSafeArray來訪問,就象是特別爲一維的字節數組所設計的一個成員函數集。

#include

請參閱:COleVariant, CRecordset, CDatabase

 

COleSafeArray類成員

構造 COleSafeArray 構造一個COleSafeArray對象

操作

Attach 給COleSafeArray對象以存在的VARIANT數組的控制

Clear 釋放基VARIANT中的所有數據

Detach 將VARIANT數組從COleSafeArray對象中分離出來(這將使數據不會被釋放)

Win32 API 包裝 AccessData 獲取一個指向數組數據的指針

AllocData 爲數組分配內存

AllocDescriptor 爲安全數組描述符分配內存

Copy 創建一個已存在的數組的拷貝

Create 創建一個安全數組

Destroy 銷燬一個已經存在的數組

DestroyData 銷燬一個安全數組中的數據

DestroyDescriptor 銷燬一個安全數組的描述符

GetDim 返回數組的維數

GetElement 獲取安全數組中的一個單一元素

GetElemSize 返回安全數組中一個元素的按字節表示的大小

GetLBound 返回一個安全數組任一維的下界

GetUBound 返回一個安全數組任一維的上界

Lock 增加一個數組的加鎖計數,並將一個指向數組數據的指針放到數組描述符中

PtrOfIndex 返回一個指向被索引的元素的指針

PutElement 將一個單一的元素放入數組中

Redim 改變一個安全數組的最不重要(最右邊)的邊界

UnaccessData 減小一個數組的加鎖計數,並使由AccessData獲得的指針無效

Unlock 減小一個數組的加鎖以使它能被釋放或改變大小

一維數組操作 CreateOneDim 創建一個一維的COleSafeArray對象

GetOneDimSize 返回一個一維的COleSafeArray對象中的元素個數

ResizeOneDim 改變一個一維的COleSafeArray對象中的元素個數

操作 operator = 將一些值(包括SAFEARRAY,VARIANT,COleVariant,或COleSafeArray對象)拷貝到COleSafeArray對象中

operator == 比較兩個不同的數組(SAFEARRAY,VARIANT,ColeVariant,或COleSafeArray對象)

operator

COleSafeArray::COleSafeArray

COleSafeArray();

COleSafeArray( const SAFEARRAY& saSrc, VARTYPE vtSrc );

COleSafeArray( LPCSAFEARRAY psaSrc, VARTYPE vtSrc );

COleSafeArray( const COleSafeArray& saSrc );

COleSafeArray( const VARIANT& varSrc );

COleSafeArray( LPCVARIANT pSrc );

COleSafeArray( const COleVariant& varSrc );

參數: saSrc 要被拷貝到新的COleSafeArray對象中去的已經存在的COleSafeArray對象或SAFEARRAY。

vtSrc 新的COleSafeArray對象的VARTYPE。

psaSrc 一個指向要被拷貝到新的COleSafeArray對象中去的SAFEARRAY的指針。

varSrc 要被拷貝到新的COleSafeArray對象中去的已經存在的VARIANT或者COleVariant。

pSrc 一個指向要被拷貝到新的COleSafeArray對象中去的VARIANT對象的指針。

說明:

所有這些構造函數都創建一個新的COleSafeArray對象。如果沒有參數,則創建的是一個空的COleSafeArray對象(VT_EMPTY)。如果COleSafeArray是從另一個數組拷貝來的,並且這個數組的VARTYPE並不是完全確定的(一個COleSafeArray,COleVariant,或者VARIANT),則源數組中的VARTYPE被保留,並且不需要說明。如果COleSafeArray是從另一個數組拷貝而來,並且該數組的VARTYPE是不知道的,則VARTYPE必須用vtSrc參數來指定。

如果出錯,則函數拋出一個CMemoryException或COleException。

請參閱:VariantCopy

-------------------------------------------------------------------------------------------------------------------------------

VARTYPE

An enumeration type used in VARIANT, TYPEDESC, OLE property sets, and safe arrays.

The enumeration constants listed in the following VARENUM section are valid in the vt field of a VARIANT structure.

typedef unsigned short VARTYPE;

 

enum VARENUM{

 

     VT_EMPTY     = 0,     // Not specified.

     VT_NULL      = 1,     // Null.

     VT_I2        = 2,     // 2-byte signed int.

     VT_I4        = 3,     // 4-byte signed int.

     VT_R4        = 4,     // 4-byte real.

     VT_R8        = 5,     // 8-byte real.

     VT_CY        = 6,     // Currency.

     VT_DATE      = 7,     // Date.

     VT_BSTR      = 8,     // Binary string.

     VT_DISPATCH = 9,     // IDispatch

     VT_ERROR     = 10,    // Scodes.

     VT_BOOL      = 11,    // Boolean; True=-1, False=0.

     VT_VARIANT   = 12,    // VARIANT FAR*.

     VT_UNKNOWN   = 13,    // IUnknown FAR*.

     VT_UI1       = 17,    // Unsigned char.

     // Other constants that are not valid in VARIANTs omitted here.

};

     VT_RESERVED = (int) 0x8000

     // By reference, a pointer to the data is passed.

     VT_BYREF     = (int) 0x4000

     VT_ARRAY     = (int) 0x2000   // A safe array of the data is passed.

轉自http://liuzixue99.blog.163.com/blog/static/6084949620098273219958/ 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章