在使用COM/DCOM写组件时经常要传递数组,一般比如SHORT,LONG等指针可以直接传递相应的指针,但是当遇到需要传递BYTE数组就有问题了,COM不支持BYTE类型参数,传递BYTE数组也就无从说起了。经过查找资料发现使用VARIANT变量可以传递任何类型的数组,随将使用VARIANT数组的方法总结一下。其实在VARIANT传递数组的方法非常简单,只要理解SAFEARRAY数组的使用方法即可,实质上SafeArray就是将通常的数组增加一个描述符,说明其维数、长度、边界、元素类型等信息。SafeArray使用步骤如下:
步骤一:生成SafeArray数组
VARIANT varChunk;
SAFEARRAY *psa; //使用数组整理读取的数据
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].cElements =len; //设置数组的大小
rgsabound[0].lLbound = 0;
psa = SafeArrayCreate(VT_UI1,1,rgsabound); //创建SafeArray数组
步骤二:给SafeArray赋值与读取
给SafeArray赋值或读取有两种方法,一种是直接读取数据缓冲区,一种是通过函数一个一个读取数组每个变量值,很显然前一种方法比后一种方法的效率要高很多,下面就两种方法分别给出相应代码
(1) 直接读取缓冲区
读取
BYTE *buf;
SafeArrayAccessData(psa, (void **)&buf); //安全指针
SafeArrayUnaccessData(psa); //关闭后仍然可读取数据,但不能写入
写入
BYTE *buf;
SafeArrayAccessData(psa, (void **)&buf); //安全指针
for(int i=0;i<len;i++)buf[i]=(i+2)%256; 直接修改缓冲区<="" p="">
SafeArrayUnaccessData(psa);
(2) 利用函数单个读取(SafeArrayGetElement,SafeArrayPutElement)
读取
long len=psa->rgsabound[0].cElements;
BYTE *pData=new BYTE[len];
for (int i=0;i<len;i++)< p="">
{
::SafeArrayGetElement(psa,&i,pData+i)
}
写入
long len=psa->rgsabound[0].cElements;
for (int i=0;i<len;i++)< p="">
{
::SafeArrayPutElement(psa,&i,pData[i])
}
步骤三:将安全数组与VARIANT相互赋值
将安全数组赋值给VARIANT
VARIANT varChunk;
varChunk.vt = VT_ARRAY|VT_UI1; //数组类型
varChunk.parray = psa;
将VARIANT赋值给安全数组
SAFEARRAY *psa=varChuank.parray;
通过以上三步就能够很容易地在数组和VARIANT变量之间传递数据,另外VARIANT还可以表示其他很多类型的数据,现将VARIANT支持的数据类型列出:
unsigned char 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
IUnknown FAR* punkVal; VT_UNKNOWN
IDispatch FAR* pdispVal; VT_DISPATCH
SAFEARRAY FAR* parray; VT_ARRAY|*
unsigned char 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; VT_BYREF