学会使用SafeArray 之 Delphi 篇.docx

上传人:b****4 文档编号:12205415 上传时间:2023-04-17 格式:DOCX 页数:8 大小:16.37KB
下载 相关 举报
学会使用SafeArray 之 Delphi 篇.docx_第1页
第1页 / 共8页
学会使用SafeArray 之 Delphi 篇.docx_第2页
第2页 / 共8页
学会使用SafeArray 之 Delphi 篇.docx_第3页
第3页 / 共8页
学会使用SafeArray 之 Delphi 篇.docx_第4页
第4页 / 共8页
学会使用SafeArray 之 Delphi 篇.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

学会使用SafeArray 之 Delphi 篇.docx

《学会使用SafeArray 之 Delphi 篇.docx》由会员分享,可在线阅读,更多相关《学会使用SafeArray 之 Delphi 篇.docx(8页珍藏版)》请在冰豆网上搜索。

学会使用SafeArray 之 Delphi 篇.docx

学会使用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;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1