SAFEARRAY与SAFEARRAYBOUND用法
来源:互联网 发布:mac下搭建lamp环境 编辑:程序博客网 时间:2024/06/05 01:29
SAFEARRAY与SAFEARRAYBOUND使用方法总结:
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作为参数传送出去了。
(5).销毁创建的SafeArray 安全数组
SafeArrayDestroyData(safeArray);
SafeArrayDestroy(safeArray);
//例子代码如下:
/*
* this function read local file to blob fileds.
*/
_COMMON_API_ BOOLWINAPI ReadPathFileToBlob(_RecordsetPtr& rs,LPCTSTR sField,LPCTSTR lpFilePath){BOOL bFlag = TRUE;CFile file;if (file.Open(lpFilePath,CFile::modeRead | CFile::typeBinary)){long lLen = file.GetLength();if (lLen > 0){byte* lpFileBuffer = new byte[lLen+1];ASSERT(lpFileBuffer != NULL);memset(lpFileBuffer,0,lLen+1);file.Read(lpFileBuffer,lLen);file.Close();SAFEARRAYBOUND sArrayBound[1];sArrayBound[0].lLbound= 0;sArrayBound[0].cElements= lLen;SAFEARRAY *safeArray = NULL; safeArray = SafeArrayCreate(VT_UI1, 1, sArrayBound);ASSERT(safeArray != NULL);for (long i = 0; i < lLen; i++)SafeArrayPutElement(safeArray, &i, lpFileBuffer++);VARIANT varBLOB;varBLOB.vt = VT_ARRAY | VT_UI1;varBLOB.parray = safeArray;rs->GetFields()->GetItem(sField)->AppendChunk(varBLOB);SafeArrayDestroyData(safeArray);SafeArrayDestroy(safeArray);}}else{bFlag = FALSE;}return bFlag;}
读取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);
//例子代码如下:
/** * this fucntion read database blob fileds to local file.*/_COMMON_API_ BOOLWINAPI ReadBlobToLocalFile(_RecordsetPtr& rs,LPCTSTR sField,LPCTSTR lpFilePath){BOOL bFlag = TRUE;long lDataSize = rs->GetFields()->GetItem(sField)->ActualSize;if (lDataSize > 0){_variant_t varBLOB = rs->GetFields()->GetItem(sField)->GetChunk(lDataSize);if ((VT_ARRAY | VT_UI1) == varBLOB.vt){/*BYTE lpFileBuffer[lDataSize+1];memset(lpFileBuffer,0,lDataSize+1);for (long l = 0 ; l < lDataSize ; l++)SafeArrayGetElement(varBLOB.parray,&l,lpFileBuffer++);*/char* buffer = NULL;SafeArrayAccessData(varBLOB.parray,(void **)&buffer);::DeleteFile(lpFilePath);CFile file;if (file.Open(lpFilePath,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary)){file.Write(buffer,lDataSize);file.Close();}else{bFlag = FALSE;}SafeArrayUnaccessData(varBLOB.parray);}else{bFlag = FALSE;}}else{bFlag = FALSE;}return bFlag;}
这种方法读写SafeArray都可以,它直接操纵SafeArray的数据缓冲区,比用SafeArrayGetElement和 SafeArrayPutElement速度快。
特别适合于读取数据。但用完之后不要忘了调用::SafeArrayUnaccessData (psa),否则会出错的。
- SAFEARRAY与SAFEARRAYBOUND用法
- SAFEARRAY与SAFEARRAYBOUND用法
- SAFEARRAY与SAFEARRAYBOUND用法
- SAFEARRAY与SAFEARRAYBOUND用法
- SAFEARRAY与SAFEARRAYBOUND用法
- SAFEARRAY与SAFEARRAYBOUND的相关知识点
- SAFEARRAY基本用法详解
- SAFEARRAY
- SafeArray
- SAFEARRAYBOUND Structure [Automation]
- # JaCOB与Variant与SafeArray与多维数组
- SafeArray (转贴)
- SafeArray.java
- SAFEARRAY解释
- SAFEARRAY简介
- SAFEARRAY使用
- SAFEARRAY使用方法
- SAFEARRAY类型
- java8的lambda表达式以及方法引用
- 2014年互联网金融安全报告
- 欢迎使用CSDN-markdown编辑器
- Webrtc 系列之一: ubuntu 下webrtc的环境搭建 和编译为安卓APK
- Windows Mobile开发文章收藏
- SAFEARRAY与SAFEARRAYBOUND用法
- 国产手机寒冬将至:成也安卓败也安卓?
- 时间函数
- EL表达式遍历Map集合
- linux ubuntu12.04上opencv2.4.7 cmake2.8.12.1 qt4环境搭建
- spi driver framework
- 全排列非递归实现
- java之:& 和 &&的区别
- android-HttpClient