OleVariant类型变量的处理,急!!!!!!!!!!!!!200分(200分)

  • 主题发起人 主题发起人 fartripLiao
  • 开始时间 开始时间
F

fartripLiao

Unregistered / Unconfirmed
GUEST, unregistred user!
有一DCOM组件,需要处理其事件,但事件中返回的变量类型为OLEVariant,不知道怎么处理.
procedure TForm1.NetNode1History(ASender: TObject;
var HistoryEvents: OleVariant; out Proccessed: WordBool);

是一个结构数组,其结构定义如下:
HistoryEvent = packed record
EventID: Smallint;
CtrlAddress: Smallint;
PointAddress: Smallint;
CardZone: Integer;
CardNo: Integer;
LinkageNo: Smallint;
UserZone: Smallint;
EventTime: TDateTime;
end;

请各位大侠指教.
请附上完整的处理代码过程
 
for i :=VarArrayLowBound(HistoryEvents,1) to VarArrayHighBoun (HistoryEvents,1) do
showmessage(HistoryEvents[0])
用这个循环来处理,就可以看到里面所有值了!
 
几乎所有的VarArray开头的函数都无法用,一运行就会出错.
请高手指教.
 
Type
PHistoryEvent=^THistoryEvent;
THistoryEvent = packed record
EventID: Smallint;
CtrlAddress: Smallint;
PointAddress: Smallint;
CardZone: Integer;
CardNo: Integer;
LinkageNo: Smallint;
UserZone: Smallint;
EventTime: TDateTime;
end;

function hInfoToVariant(Info:PHistoryEvent):Variant;
Var
Data:Pointer;
begin
Result:=VarArrayCreate([0,sizeof(THistoryEvent)-1],varByte);
Data:=VarArrayLock(Result);
Try
CopyMemory(Data,PByte(Info),sizeof(THistoryEvent));
Finally
VarArrayUnLock(Result)
end;
end;

function VariantTohInfo(vData:Variant):THistoryEvent;
Var
Len:Integer;
Data:Pointer;
begin
Len:=VarArrayHighBound(vData,1)+1;
if Len<>sizeof(THistoryEvent) then
Raise Exception.Create('数据包无效!');

Data:=VarArrayLock(vData);
Try
CopyMemory(PByte(@Result),Data,Len);
Finally
VarArrayUnLock(vData)
end;
end;
 
请appfirst注意,HistoryEvents: OleVariant是一个结构HistoryEvent的一维数组,而不是一个HistoryEvent变量,我试过,得出的值不对,
请appfirst再想想,
 
关键在于你是如何传递参数的?
是按数组?还是直接传递?
 
你試試直接用:
HistoryEvent(OleVariant).Smallint
HistoryEvent(OleVariant).CtrlAddress
這樣試試看可不可以!
 
"几乎所有的VarArray开头的函数都无法用,一运行就会出错.请高手指教. "
有可能你的HistoryEvent是空的
 
一般而言,使用ole类型传送缓冲区都是使用我的这个方法,在99年我就是这么写的,如果不对,那就应该去询问提供服务的人员。
 
olevariant不可能是一个结构,他没有哪个类型,但他的数据可以是一个结构,明白?
 
这个事件返回的数据就是一个结构的数组?
 
这样吧我说清楚些,
此事件传递过来的变量HistoryEvents: OleVariant本来就是一个数组,简单的来说,传递过来的数据,可能是一条事件,也可能是多条事件.
所以它一定是一个数组,
而且每一个元素都是上述申明的结构以下附上C++BUILDER处理代码,
而且我们的客户在用VC++来处理这个变量时,其变量类型就是,OLEVARIANT类型的,
在C++BUILDER中的类型见如下代码
void __fastcall TServerImpl::OnHistory(WORD NodeID,LPSAFEARRAY HistoryEvents,
VARIANT_BOOL* Proccessed)
int iCount=HistoryEvents->rgsabound[0].cElements;
tagHistoryEvent *phes=(tagHistoryEvent*)HistoryEvents->pvData;
BOOL bSuccessed=TRUE;
int iContents;
long Flags=0;
try{
for(int i=0;i<iCount;i++){
pParas->ParamByName(WideString("@MessageID"))->Value=phes.EventID;
pParas->ParamByName(WideString("@CardID"))->Value=phes.CardNo;
pParas->ParamByName(WideString("@CardZoneID"))->Value=phes.CardZone;
pParas->ParamByName(WideString("@PointAddress"/*"Address"*/))->Value=phes.PointAddress;
pParas->ParamByName(WideString("@EventTime"))->Value=phes.EventTime;
pParas->ParamByName(WideString("@controlMachineAddress"))->Value=phes.CtrlAddress;
pParas->ParamByName(WideString("@SubPointIP"))->Value=*(NodeNames[NodeID]);
iContents=EventClass[phes.EventID];
pParas->ParamByName(WideString("@Contents"))->Value=iContents;

}

以上的C++BUILDER的代码是完全正确的,此代码不需要任何怀疑,因为这用这些代码编译的软件都运行正常.

也曾试过将其当作为LPSAFEARRAY 类型来处理,也不行,无法读出正确的数据.
请各位高手,指点
 
这段代码不是和我写的一样吗,不同的是缓冲中不是一个结构,而是一个结构数组。
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
Init: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
DateTimePicker1: TDateTimePicker;
Edit8: TEdit;
Edit9: TEdit;
Edit10: TEdit;
Edit11: TEdit;
Edit12: TEdit;
Edit13: TEdit;
Edit14: TEdit;
Button2: TButton;
Edit15: TEdit;
procedure InitClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}


Type
PHistoryEvent=^THistoryEvent;
THistoryEvent = packed record
EventID: Smallint;
CtrlAddress: Smallint;
PointAddress: Smallint;
CardZone: Integer;
CardNo: Integer;
LinkageNo: Smallint;
UserZone: Smallint;
EventTime: TDateTime;
end;
THistoryEvents=Array of THistoryEvent;
Var
Info:THistoryEvent;
vData:Variant;

function hInfoToVariant(Info:PHistoryEvent):Variant;
Var
Data:Pointer;
begin
Result:=VarArrayCreate([0,sizeof(THistoryEvent)-1],varByte);
Data:=VarArrayLock(Result);
Try
CopyMemory(Data,PByte(Info),sizeof(THistoryEvent));
Finally
VarArrayUnLock(Result)
end;
end;

function hInfosToVariant(Info:THistoryEvents):Variant;
Var
i:Integer;
Data:Pointer;
begin
Result:=VarArrayCreate([0,Length(Info)-1,0,sizeof(THistoryEvent)-1],varByte);
Data:=VarArrayLock(Result);
Try
For i:=Low(Info) to High(Info) do
begin
CopyMemory(Data,PByte(@Info),sizeof(THistoryEvent));
Inc(PChar(Data),sizeof(THistoryEvent));
end;
Finally
VarArrayUnLock(Result)
end;
end;

function VariantTohInfo(vData:Variant):THistoryEvent;
Var
Len:Integer;
Data:Pointer;
begin
Len:=VarArrayHighBound(vData,1)+1;
if Len<>sizeof(THistoryEvent) then
Raise Exception.Create('数据包无效!');

Data:=VarArrayLock(vData);
Try
CopyMemory(PByte(@Result),Data,Len);
Finally
VarArrayUnLock(vData)
end;
end;

function VariantTohInfos(vData:Variant):THistoryEvents;
Var
i:Integer;
Len:Integer;
Data:Pointer;
begin
Len:=VarArrayHighBound(vData,1)+1;
SetLength(Result,Len);

Data:=VarArrayLock(vData);
Try
For i:=Low(Result) to High(Result) do
begin
CopyMemory(PByte(@Result),Data,sizeof(THistoryEvent));
Inc(PChar(Data),sizeof(THistoryEvent));
end;
Finally
VarArrayUnLock(vData)
end;
end;

procedure TForm1.InitClick(Sender: TObject);
Var
i:Integer;
Infos:THistoryEvents;
begin
SetLength(Infos,3);
For i:=0 to 2 do
begin
With Infos do
begin
EventID:=StrToInt(Edit1.Text)+i;
CtrlAddress:=StrToInt(Edit2.Text)+i;
PointAddress:=StrToInt(Edit3.Text)+i;
CardZone:=StrToInt(Edit4.Text)+i;
CardNo:=StrToInt(Edit5.Text)+i;
LinkageNo:=StrToInt(Edit6.Text)+i;
UserZone:=StrToInt(Edit7.Text)+i;
EventTime:=DateTimePicker1.DateTime+i;
end;
end;
vData:=hInfosToVariant(Infos);
end;

procedure TForm1.Button2Click(Sender: TObject);
Var
vInfo:THistoryEvents;
begin
vInfo:=VariantTohInfos(vData);
Edit8.Text:=IntToStr(vInfo[0].EventID)+','+IntToStr(vInfo[1].EventID)+','+IntToStr(vInfo[2].EventID);
Edit9.Text:=IntToStr(vInfo[0].CtrlAddress)+','+IntToStr(vInfo[1].CtrlAddress)+','+IntToStr(vInfo[2].CtrlAddress);
Edit10.Text:=IntToStr(vInfo[0].PointAddress)+','+IntToStr(vInfo[1].PointAddress)+','+IntToStr(vInfo[2].PointAddress);
Edit11.Text:=IntToStr(vInfo[0].CardZone)+','+IntToStr(vInfo[1].CardZone)+','+IntToStr(vInfo[2].CardZone);
Edit12.Text:=IntToStr(vInfo[0].CardNo)+','+IntToStr(vInfo[1].CardNo)+','+IntToStr(vInfo[2].CardNo);
Edit13.Text:=IntToStr(vInfo[0].LinkageNo)+','+IntToStr(vInfo[1].LinkageNo)+','+IntToStr(vInfo[2].LinkageNo);
Edit14.Text:=IntToStr(vInfo[0].UserZone)+','+IntToStr(vInfo[1].UserZone)+','+IntToStr(vInfo[2].UserZone);
Edit14.Text:=DateTimeToStr(vInfo[0].EventTime)+','+DateTimeToStr(vInfo[1].EventTime)+','+DateTimeToStr(vInfo[2].EventTime);
end;

end.
 
object Form1: TForm1
Left = 68
Top = 69
Width = 696
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Init: TButton
Left = 64
Top = 368
Width = 75
Height = 25
Caption = 'HtoV'
TabOrder = 0
OnClick = InitClick
end
object Edit1: TEdit
Left = 72
Top = 24
Width = 121
Height = 21
TabOrder = 1
Text = '1111'
end
object Edit2: TEdit
Left = 72
Top = 56
Width = 121
Height = 21
TabOrder = 2
Text = '2222'
end
object Edit3: TEdit
Left = 72
Top = 88
Width = 121
Height = 21
TabOrder = 3
Text = '333'
end
object Edit4: TEdit
Left = 72
Top = 120
Width = 121
Height = 21
TabOrder = 4
Text = '444'
end
object Edit5: TEdit
Left = 72
Top = 152
Width = 121
Height = 21
TabOrder = 5
Text = '555'
end
object Edit6: TEdit
Left = 72
Top = 184
Width = 121
Height = 21
TabOrder = 6
Text = '666'
end
object Edit7: TEdit
Left = 72
Top = 216
Width = 121
Height = 21
TabOrder = 7
Text = '777'
end
object DateTimePicker1: TDateTimePicker
Left = 72
Top = 256
Width = 121
Height = 21
Date = 37938.896322696760000000
Time = 37938.896322696760000000
TabOrder = 8
end
object Edit8: TEdit
Left = 248
Top = 24
Width = 121
Height = 21
TabOrder = 9
end
object Edit9: TEdit
Left = 248
Top = 56
Width = 121
Height = 21
TabOrder = 10
end
object Edit10: TEdit
Left = 248
Top = 88
Width = 121
Height = 21
TabOrder = 11
end
object Edit11: TEdit
Left = 248
Top = 120
Width = 121
Height = 21
TabOrder = 12
end
object Edit12: TEdit
Left = 248
Top = 152
Width = 121
Height = 21
TabOrder = 13
end
object Edit13: TEdit
Left = 248
Top = 184
Width = 121
Height = 21
TabOrder = 14
end
object Edit14: TEdit
Left = 248
Top = 216
Width = 121
Height = 21
TabOrder = 15
end
object Button2: TButton
Left = 304
Top = 368
Width = 75
Height = 25
Caption = 'VtoH'
TabOrder = 16
OnClick = Button2Click
end
object Edit15: TEdit
Left = 248
Top = 256
Width = 417
Height = 21
TabOrder = 17
end
end
 
function hInfosToVariant(Info:THistoryEvents):Variant;
function VariantTohInfos(vData:Variant):THistoryEvents;
这两个函数就是处理数组情况的。
 
希望对你能有帮助[:)]
 
按照你调用的顺序
vData:=hInfosToVariant(Infos);
function hInfosToVariant(Info:THistoryEvents):Variant;
虽然事件的变量是一个数组,但好象不能直接就这样认为.我试过,会出错的.
vInfo:=VariantTohInfos(vData);
请再想想,我实在头大.
 
我试验过没有问题才给你的,从你的c++builder的代码上看是这样的,你那边出什么错误?
 
事件的条数不对,总是,26条.
得出的数据也不对,
每条事件得出的数据都不对.
 
后退
顶部