PSafeArray使用安全数组求解,内存块已取到,个数也对得上,可是值却怎么取也不是对

[复制链接]
查看11 | 回复4 | 2021-1-27 07:04:29 | 显示全部楼层 |阅读模式
之前没有使用过安全数组,
这是对接一个VB做的Com接口,内存块已经取到//现在遍历出每个元素的结构体,可是怎么读也不对,还望各位指点一点,没有过这方面的经验

PosLogInfo=packedrecord
ReadMark:Byte;
CardNo:Double;
SFType:Smallint;
SFMealTypeID:Smallint;
SFAmount:Double;
CardBalance:Double;
SFDate:TDateTime;
CardUseTimes:Integer;
SFOpterNo:Smallint;
OrderDate:TDateTime;
ProductID:array[0..9]ofInteger;
ProductNum:array[0..9]ofInteger;
end;
functionSafeArrayToText(p:PSafeArray):string;
var
RBound:TVarArrayBound;
i,UCount:Integer;
xfinfo:PosLogInfo;//消费记录的结构体
begin
VarResultCheck((SafeArrayGetLBound(p,1,RBound.LowBound)));
VarResultCheck(SafeArrayGetUBound(p,1,UCount));
RBound.ElementCount:=UCount-RBound.LowBound;
//元素的个数,没有错,符合接口提示的22个.
//现在遍历出每个元素的结构体,可是怎么读也不对,还望各位指点一点,没有过这方面的经验
fori:=RBound.LowBoundtoRBound.ElementCountdo
begin
FillChar(xfinfo,SizeOf(xfinfo),0);
//这句不知道要如何写,按理是对的,可是不知道怎么回事,读出的值总是不对,而且每条竟然都是一样的
VarResultCheck(SafeArrayGetElement(p,i,xfinfo));
Memo1.Lines.Add('CardNo:'+FloatToStr(xfinfo.CardNo));
Memo1.Lines.Add('SFType:'+FloatToStr(xfinfo.SFType));
Memo1.Lines.Add('SFAmount:'+FloatToStr(xfinfo.SFAmount));
Memo1.Lines.Add('CardBalance:'+FloatToStr(xfinfo.CardBalance));
Memo1.Lines.Add('SFDate:'+formatdatetime('',xfinfo.SFDate));
end;
end;
//FillChar已经清0了结构体,遍历的值竟然全是一样的,说明应该已经有赋值了,而且还不对
CardNo:0
SFType:5120
SFAmount:3.79442416006077E-321
CardBalance:6.21476085095821E-317
SFDate:1899-12-30
CardNo:0
SFType:5120
SFAmount:3.79442416006077E-321
CardBalance:6.21476085095821E-317
SFDate:1899-12-30
CardNo:0
SFType:5120
SFAmount:3.79442416006077E-321
CardBalance:6.21476085095821E-317
SFDate:1899-12-30
CardNo:0
SFType:5120
SFAmount:3.79442416006077E-321
CardBalance:6.21476085095821E-317
SFDate:1899-12-30

分 -->
回复

使用道具 举报

千问 | 2021-1-27 07:04:29 | 显示全部楼层
SafeArrayGetElement(p,i,xfinfo);p是啥
SafeArrayGetElement(目标数组,数组引索号,存读出的数数组)
回复

使用道具 举报

千问 | 2021-1-27 07:04:29 | 显示全部楼层
引用1楼sololie的回复:SafeArrayGetElement(p,i,xfinfo);p是啥
SafeArrayGetElement(目标数组,数组引索号,存读出的数数组)

p:PSafeArray,是安全数组

你好,我的朋友也是这样说,返回的值也应该是个数组,那我应该如何把这个数组转化我的消费记录的结构体呢?
SafeArrayGetElement(目标数组,数组引索号,存读出的数数组)
回复

使用道具 举报

千问 | 2021-1-27 07:04:29 | 显示全部楼层
试试
var
RBound:TVarArrayBound;
i,UCount:Integer;
xfinfoArr:arrayofPosLogInfo;
begin
VarResultCheck((SafeArrayGetLBound(p,1,RBound.LowBound)));
VarResultCheck(SafeArrayGetUBound(p,1,UCount));
RBound.ElementCount:=UCount-RBound.LowBound;
SetLength(xfinfoArr,SizeOf(PosLogInfo)*22);
fori:=RBound.LowBoundtoRBound.ElementCountdo
begin
//FillChar(xfinfo,SizeOf(xfinfo),0);
VarResultCheck(SafeArrayGetElement(p,i,xfinfoArr));
Memo1.Lines.Add('CardNo:'+FloatToStr(xfinfoArr.CardNo));
Memo1.Lines.Add('SFType:'+FloatToStr(xfinfoArr.SFType));
Memo1.Lines.Add('SFAmount:'+FloatToStr(xfinfoArr.SFAmount));
Memo1.Lines.Add('CardBalance:'+FloatToStr(xfinfoArr.CardBalance));
Memo1.Lines.Add('SFDate:'+formatdatetime('',xfinfoArr.SFDate));
end;
end;

回复

使用道具 举报

千问 | 2021-1-27 07:04:29 | 显示全部楼层
不知道你的safearray里是怎么存储的,这有个例子,数组里存的是2进制数据,把它取出来的代码:
classprocedureConvert.SafeArrayToBytes(constAData:OleVariant;
varABytes:TBytes);
var
sa:PSafeArray;
l,u:Integer;
p:Pointer;
begin
SetLength(ABytes,0);
if(TVarData(AData).VType=VT_ARRAYorVT_UI1)then
begin
sa:=TVarData(AData).VAny;
ifS_OKSafeArrayGetLBound(sa,1,l)thenExit;
ifS_OKSafeArrayGetUBound(sa,1,u)thenExit;
if(u=0)then
Exit;
ifS_OK=SafeArrayAccessData(sa,p)then
try
SetLength(ABytes,u-l+1);
CopyMemory(@ABytes[0],p,u-l+1);
finally
SafeArrayUnaccessData(sa);
end;
end;
end;
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行