猛料資料,首先介紹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就是將通常的陣列增加乙個描述符,說明其維數 長度 邊界 元素型別等資...