首先Com提供语言无关的array,我们可以这样使用:
//定义safe array bound
SAFEARRAYBOUND rgsabound[2];
rgsabound[0].cElements = 3;
rgsabound[0].lLbound = 0;
rgsabound[1].cElements = 4;
rgsabound[1].lLbound = 0;
//new safe array
SAFEARRAY* psa = SafeArrayCreate(VT_R8,2,rgsabound);
long rgIndices[] = {2,1}; //访问array[1][2],这里顺序相反
double lElem;
SafeArrayGetElement(psa,rgIndices,&lElem);
//稍后,你可以使用SafeArrayDestroy销毁这个sa
//delete safe array
SafeArrayDestroy(psa);
Com定义了CComSafeArray,这次真的是为了简化操作,它提供了如下功能:
//定义safe array bound
SAFEARRAYBOUND rgsabound[2];
rgsabound[0].cElements = 3;
rgsabound[0].lLbound = 0;
rgsabound[1].cElements = 4;
rgsabound[1].lLbound = 0;
//new safe array
SAFEARRAY* psa = SafeArrayCreate(VT_R8,2,rgsabound);
long rgIndices[] = {2,1}; //访问array[1][2],这里顺序相反
double lElem;
SafeArrayGetElement(psa,rgIndices,&lElem);
//稍后,你可以使用SafeArrayDestroy销毁这个sa,不过我还将用到它,暂时不销毁
//使用CComSafeArray必须#include
//A.CComSafeArray构造函数
//1.比较常用的,构造一个一维数组
CComSafeArray
csa1(5,0); //构造一个一维数组,指定元素个数和lbound
//2.使用SAFEARRAYBOUND构造指定维数、lbound信息数组,这个不常用,因为指定多维数组可以有其他方法,参看3
SAFEARRAYBOUND sabound2[3]; //我很坚持的指定lbound为0,尽管这里只是示例,因为我是个c程序员,我不想因为特殊lbound出错。
sabound2[0].cElements = 2;
sabound2[0].lLbound = 0;
sabound2[1].cElements = 4;
sabound2[1].lLbound = 0;
sabound2[2].cElements = 3;
sabound2[2].lLbound = 0;
CComSafeArray
csa2(sabound2); //构造了指定维数的数据,数据类型是long
//3.手动构造多维数组,让一切自己都很明白
CComSafeArrayBound bound1(2);
CComSafeArrayBound bound2(4);
CComSafeArrayBound bound3(3);
CComSafeArrayBound rgBounds[] = {bound1,bound2,bound3};
CComSafeArray
csa3(rgBounds,3); //接受一个CComSafeArrayBound参数和维度标志创建数组
//4.通过已有的SAFEARRAY指针创建数组
CComSafeArray
csa4(psa);
//5.通过已有的SAFEARRAY引用创建数组
CComSafeArray
csa5(*psa);
//6.拷贝构造
CComSafeArray
csa6(csa5);
//B.赋值,CComSafeArray赋值,如果成功的话,之前的目标数组被释放
csa6 = csa4;
csa4 = csa1; //注意,这种不同类型的赋值可以编译通过,但是运行有问题
//C.和SAFEARRAY的交互
//1.Attach方法
csa4.Attach(psa); //psa将被销毁,所以没有必要再调用SafeArrayDestroy方法了
//2.Detach方法
csa4.Detach(psa);
//delete safe array
SafeArrayDestroy(psa);
//D.操作
//1.获取尺寸、类型信息等
ULONG dulong;
dulong = csa1.GetLowerBound();
dulong = csa1.GetUpperBound();
dulong = csa1.GetCount();
UINT duint;
duint = csa1.GetDimensions();
VARTYPE dtype;
dtype = csa1.GetType();
bool dsizeable;
dsizeable = csa1.IsSizable();
//2.直接获取底层SAFEARRAY
psa = csa1.GetSafeArrayPtr();
//3.大小调整
csa1.Resize(5,0); //重新调整大小和lbound
csa1.Resize(rgBounds); //使用SAFEARRAYBOUND调整
//4.Add方法
CComSafeArray
dcsa4;
dcsa4.Add(5); //添加到末尾一个5,如果SAFEARRAY为NUL,则Create一个
int added4[] = {1,4,7,8,9,22};
dcsa4.Add(6,added4); //添加对于类型的数组到尾部
dcsa4.Add(dcsa4); //添加CComSafeArray数组
//5.访问方法
int dint4 = dcsa4.GetAt(2); //返回第2个元素
dcsa4.SetAt(3,dint4); //修改一个元素,对于SetAt还有第三个参数,标志是否拷贝,在需要生命周期管理的类型(譬如BSTR)上有意义
int drgind[] = {1,1};
csa1.MultiDimGetAt(drgind,dint4); //获取多维数组元素
csa1.MultiDimSetAt(drgind,dint4); //修改多维数组元素
dcsa4[1] = 5; //定义了operator[]
CComSafeArray是一个模板,支持它的模板参数如下(表格中的C++ Type列):
VARTYPE
C++ TYPE
VT_I1
char
VT_I2
short
VT_I4
int
VT_I4
long
VT_I8
long long
VT_UI1
byte
VT_UI2
ushort
VT_UI4
uint
VT_UI4
ulong
VT_UI8
ulonglong
VT_R4
float
VT_R8
double
VT_DECIMAL
decimal
VT_VARIANT
variant
VT_CY
currency
VT_BSTR
BSTR
VT_DISPATCH
IDispatch pointer
VT_UNKNOWN
IUnknown pointer
模板参数是在C++中使用的,所以遵从C++语法的类型数据并且在这个表格中的,都可以作为CComSafeArray的模板参数。