学会使用SafeArray 之 Delphi 篇.docx
- 文档编号:12205415
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:8
- 大小:16.37KB
学会使用SafeArray 之 Delphi 篇.docx
《学会使用SafeArray 之 Delphi 篇.docx》由会员分享,可在线阅读,更多相关《学会使用SafeArray 之 Delphi 篇.docx(8页珍藏版)》请在冰豆网上搜索。
学会使用SafeArray之Delphi篇
学会使用SafeArray之Delphi篇
学会使用SafeArray之Delphi篇分类:
Delphi
2010-11-0514:
07
966人阅读
评论(0)
收藏
举报
delphiintegerdatasetfunctionstringXX
在学习的时候曾经XX了一下,想查找关于delphi中SafeArray的用法,没想到资料竟然如此之少,甚至连一篇相对完整的都没有。
也许正如田师傅所说,现在高手们都在实行“技术封锁”了?
在CSDN技术中心有一篇关于C++的使用,说的比较详细。
鉴于手中有田师傅写的代码,特拿来一部分对照自己学习的,翻译为Delphi版本。
留作笔记,日后翻阅。
===============================================================================
SAFEARRAY的主要目的是用于automation中的数组型参数的传递。
因为在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray。
实质上SafeArray就是将通常的数组增加一个描述符,说明其维数、长度、边界、元素类型等信息。
SafeArray也并不单独使用,而是将其再包装到VARIANT类型的变量中,然后才作为参数传送出去。
在VARIANT的vt成员的值如果包含VT_ARRAY|...,那么它所封装的就是一个SafeArray,它的parray成员即是指向SafeArray的指针。
SafeArray中元素的类型可以是VARIANT能封装的任何类型,包括VARIANT类型本身。
Delphi中com组件或外部调用需要传递一个对象或者数组,这个时候可以考虑使用SafeArray。
比如三层架构中通常需要将使用的ClientDataSet数据集传出,那么就可以将DataSet转换为SafeArray,再由其他模块转换接收。
===============================================================================
代码块:
pSafeArray是一个结构体,其定义在ActiveX单元中,相关定义如下:
PSafeArray=^TSafeArray;
{$EXTERNALSYMtagSAFEARRAY}
tagSAFEARRAY=record
cDims:
Word;//数组的维数
fFeatures:
Word;//用来描述数组如何分配和如何被释放的标志
cbElements:
Longint;//数组元素的大小
cLocks:
Longint;//一个计数器,用来跟踪该数组被锁定的次数
pvData:
Pointer;//指向数据缓冲的指针
rgsabound:
array[0..0]ofTSafeArrayBound;//描述数组每维的数组结构,该数组的大小是可变的
end;
TSafeArray=tagSAFEARRAY;
{$EXTERNALSYMSAFEARRAY}
SAFEARRAY=TSafeArray;
===============================================================================
一维数组的传递:
//一维数组传递
procedureTForm1.ArrayToSafeArray(DataArray:
arrayofstring);
var
VarBound:
TVarArrayBound;
psa:
PSafeArray;
i:
Integer;
AV1:
OleVariant;
begin
//初始化OleValue
VariantInit(OleValue);
VarBound.LowBound:
=0;
VarBound.ElementCount:
=High(DataArray)+1;
psa:
=SafeArrayCreate(VT_BSTR,1,VarBound);//创建SafeArray对象
//将数组元素放到SafeArray中
fori:
=Low(DataArray)toHigh(DataArray)do
begin
AV1:
=DataArray[i];
SafeArrayPutElement(psa,i,TVarData(AV1).VPointer^);
end;
//封装到Varaint变量中
TVarData(OleValue).VType:
=VT_ARRAYorVT_BSTR;
TVarData(OleValue).VArray:
=pVarArray(psa);
end;
读取一维safeArray的步骤:
//使用SafeArrayGetLBound、SafeArrayGetUBound方法获取safeArray数组上下限
functionTForm1.SafeArrayToText(OleValue:
OleVariant):
string;
var
RVarData:
TVarData;
RBound:
TVarArrayBound;
j,UCount:
Integer;
aValue:
WideString;
begin
Result:
='';
//获取OleVaraint对象指针
RVarData:
=FindVarData(OleValue)^;
ifRVarData.VArray=nilthen
Exit;
VarResultCheck((SafeArrayGetLBound(pSafeArray(RVarData.VArray),1,RBound.LowBound)));
VarResultCheck(SafeArrayGetUBound(pSafearray(RVarData.VArray),1,UCount));
RBound.ElementCount:
=UCount-RBound.LowBound;
forj:
=RBound.LowBoundtoRBound.ElementCountdo
begin
VarResultCheck(SafeArrayGetElement(PSafeArray(RVarData.VArray),j,aValue));
ifResult=''then
Result:
=Result+aValue
else
Result:
=Result+','+aValue;
end;
end;
//另外附上将DataSet通过SafeArray传递的方法,其实为多维数组的传递:
procedureTForm1.DataSetToSafeArray(ClientData:
TClientDataSet);
var
DataArray:
TDoubleArray;
VarBound:
array[0..1]ofTVarArrayBound;
Demen:
array[0..1]ofDWORD;
psa:
PSafeArray;
i,j,k,Count:
Integer;
AV1:
OleVariant;
begin
SetLength(DataArray,ClientData.FieldCount+1,ClientData.RecordCount+1);
Count:
=0;
ClientData.First;
whilenotClientData.Eofdo
begin
fori:
=0toClientData.FieldCount-1do
begin
ifCount=0then
DataArray[i][Count]:
=ClientData.Fields[i].FieldName
else
DataArray[i][Count]:
=ClientData.Fields[i].Value;
end;
ifCount>0then
ClientData.Next;
inc(Count);
end;
//--------开始转换为SafeArray-----------
//初始化OleValue
VariantInit(OleValue);
VarBound[0].LowBound:
=0;
VarBound[0].ElementCount:
=ClientData.FieldCount+1;
VarBound[1].LowBound:
=0;
VarBound[1].ElementCount:
=ClientData.RecordCount+1;
psa:
=SafeArrayCreate(VT_BSTR,2,VarBound);
fori:
=Low(DataArray)toHigh(DataArray)do
begin
Demen[0]:
=i;
forj:
=Low(DataArray[i])toHigh(DataArray[i])do
begin
Demen[1]:
=j;
AV1:
=DataArray[i][j];
SafeArrayPutElement(psa,Demen,TVarData(AV1).VPointer^);
end;
end;
TVarData(OleValue).VType:
=VT_ARRAYorVT_BSTR;
TVarData(OleValue).VArray:
=pVarArray(psa);
end;
//读多维数组,读出后再转换为想要的格式:
functionTForm1.SafeArrayToDataSet(oleValue:
OleVariant):
string;
var
RVarData:
TVarData;
RBound:
array[0..1]ofTVarArrayBound;
Demen:
array[0..1]ofDWORD;
i,j,DCount,UCount,iCount:
Integer;
aValue:
WideString;
begin
Result:
='';
RVarData:
=FindVarData(OleValue)^;
ifRVarData.VArray=nilthen
Exit;
DCount:
=RVarData.Varray^.DimCount;//取维数
fori:
=0toDCount-1do
begin
VarResultCheck((SafeArrayGetLBound(pSafeArray(RVarData.VArray),i+1,RBound[i].LowBound)));
VarResultCheck(SafeArrayGetUBound(pSafearray(RVarData.VArray),i+1,UCount));
RBound[i].ElementCount:
=UCount-RBound[i].LowBound;
end;
forj:
=RBound[1].LowBoundtoRBound[1].ElementCountdo
begin
Demen[1]:
=j;
foriCount:
=RBound[0].LowBoundtoRBound[0].ElementCountdo
begin
Demen[0]:
=iCount;
VarResultCheck(SafeArrayGetElement(PSafeArray(RVarData.VArray),demen,aValue));
ifResult=''then
Result:
=Result+aValue
else
Result:
=Result+','+aValue;
end;
end;
end;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 学会使用SafeArray Delphi 学会 使用 SafeArray