關於SafeArray的使用說明

2021-06-07 19:56:05 字數 4064 閱讀 7420

猛料資料,首先介紹safearray使用,在介紹safearray中的結構。看完該節文章,safearray的陌生感一掃而去。

safearray 在ado程式設計中經常使用。它的主要目的是用於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描述符:

//read array from a file.

uisread=f.read(bval,chunksize);

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

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

(4)封裝到variant內:

varchunk.vt = vt_array|vt_ui1;

varchunk.parray = psa;

這樣就可以將varchunk作為引數傳送出去了。

讀取safearray中的資料的步驟:

(1)用safearraygetelement乙個乙個地讀

byte buf[lisread];

for(long index=0; 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

::safearrayunaccessdata(psa);

varchunk.vt = vt_array|vt_ui1;

varchunk.parray = psa;

這種方法讀寫safearray都可以,它直接操縱safearray的資料緩衝區,比用safearraygetelement和 safearrayputelement速度快。特別適合於讀取資料。但用完之後不要忘了呼叫::safearrayunaccessdata (psa),否則會出錯的。

以下就是safearray的win32定義:

typedef struct tagsafearray

safearray;

這個結構的成員(cdims,clocks等)是通過api函式來設定和管理的。真正的資料存放在pvdata成員中,而safearraybound結構定義該陣列結構的細節。以下就是該結構成員的簡要描述:

成員 描述

cdims

陣列的維數

ffeatures

用來描述陣列如何分配和如何被釋放的標誌

cbelements

陣列元素的大小

clocks

乙個計數器,用來跟蹤該陣列被鎖定的次數

pvdata 

指向資料緩衝的指標

rgsabound

描述陣列每維的陣列結構,該陣列的大小是可變的

rgsabound是乙個有趣的成員,它的結構不太直觀。它是資料範圍的陣列。該陣列的大小依safe array維數的不同而有所區別。rgsabound成員是乙個safearraybound結構的陣列--每個元素代表safearray的乙個維。

typedef struct tagsafearraybound

safearraybound;

維數被定義在cdims成員中。例如,乙個\'c\'類陣列的維數可以是[3][4][5]-乙個三維的陣列。如果我們使用乙個safearray來表示這個結構,我們定義乙個有三個元素的rgsabound陣列--乙個代表一維。

cdims = 3;

...safearraybound rgsabound[3];

rgsabound[0]元素定義第一維。在這個例子中ilbound元素為0,是陣列的下界。celements成員的值等於三。陣列的第二維 ([4])可以被rgsabound結構的第二個元素定義。下界也可以是0,元素的個數是4,第三維也是這樣。

要注意,由於這是乙個"c"陣列,因此由0 開始,對於其它語言,例如visual basic,或者使用乙個不同的開始。該陣列的詳細情況如下所示:

元素 celements

ilbound

rgsabound[0]  3 

0rgsabound[1] 4 

0rgsabound[2] 5

0 關於safearraybound結構其實還有很多沒說的。我們將要使用的safearray只是乙個簡單的單維位元組陣列。我們通過api函式建立陣列的時候,safearraybound將會被自動設定。只有在你需要使用複雜的多維陣列的時候,你才需要操作這個結構。

還有乙個名字為clocks的成員變數。很明顯,它與時間沒有任何的關係--它是乙個鎖的計數器。該引數是用來控制訪問陣列資料的。在你訪問它之前,你必須鎖定資料。通過跟蹤該計數器,系統可以在不需要該陣列時安全地刪除它。 

建立safearray

建立乙個單維safearray的簡單方法是通過使用safearraycreatevector api函式。該函式可分配乙個特定大小的連續記憶體塊。

safearray *psa; //

create a safe array to store the stream data //

llen is the number of bytes in the array.

psa = safearraycreatevector( vt_ui1, 0, llen );

safearraycreatevector api建立乙個safearray,並且返回乙個指向它的指標。首個引數用來定義陣列的型別--它可以是任何有效的變數資料型別。為了傳送乙個序列化的對 象,我們將使用最基本的型別--乙個非負的位元組陣列。vt--ui1代表非負整形的變數型別,1個位元組。

常數\'0\'定義陣列的下界;在c++中,通常為0。最後的引數llen定義陣列元素的個數。在我們的例子中,這與我們將要傳送物件的位元組數是一樣的。我們還沒有提陣列大小(llen)是怎樣來的,這將在我們重新考查序列化時提及。

在你訪問safearray資料之前,你必須呼叫safearrayaccessdata。該函式鎖定資料並且返回乙個指標。在這裡,鎖定陣列意味著增加該陣列的內部計數器(clocks)。 //

define a pointer to a byte array

unsigned char *pdata = null;

safearrayaccessdata( psa, (void**)&pdata );

... use the safe array

safearrayunaccessdata(psa);

相應用來釋放資料的函式是safearrayunaccessdata(),該功能釋放該引數的計數。

學會使用SafeArray

學會使用safearray也是很重要的,因為在ado程式設計中經常要用。它的主要目的是用於automation中的陣列型引數的傳遞。因為在網路環境中,陣列是不能直接傳遞的,而必須將其包裝成safearray。實質上safearray就是將通常的陣列增加乙個描述符,說明其維數 長度 邊界 元素型別等資...

學會使用SafeArray

學會使用safearray也是很重要的,因為在ado程式設計中經常要用。它的主要目的是用於automation中的陣列型引數的傳遞。因為在網路環境中,陣列是不能直接傳遞的,而必須將其包裝成safearray。實質上safearray就是將通常的陣列增加乙個描述符,說明其維數 長度 邊界 元素型別等資...

safearray 的具體使用方法

學會使用safearray也是很重要的,因為在ado程式設計中經常要用。它的主要目的是用於automation中的陣列型引數的傳遞。因為在網路環境中,陣列是不能直接傳遞的,而必須將其包裝成safearray。實質上safearray就是將通常的陣列增加乙個描述符,說明其維數 長度 邊界 元素型別等資...