![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как передать в функцию массив записей использия Variant? [WinXP]
Kolan © (2006-04-07 13:08:00)Здравствуйте,
Есть запись:
TDoublePoint = record
X: Double;
Y: Double;
end;
И есть соотв. дин. массив.:
TDoublePointArray = array of TDoublePoint;
Мне нужно передать массив такого типа функции, которая о нем ничего не знает. Пытался сделать так:
procedure TForm1.BitBtn1Click(Sender: TObject);
var
V: Variant;
Arr: TDoublePointArray;
I: Integer;
begin
SetLength(Arr, 10);
for I := Low(Arr) to High(Arr) do
begin
Arr[I].X := I;
Arr[I].Y := I * I;
end;
V := Arr;
PrintArray(TDoublePointArray(V));
end;
procedure TForm1.PrintArray(V: Variant);
var
I: Integer;
begin
for I := Low(TDoublePointArray(V)) to High(TDoublePointArray(V)) do
begin
ListBox1.Items.Add(FloatToStr(TDoublePointArray(V)[I].X) +' - '
+FloatToStr(TDoublePointArray(V)[I].Y));
end;
end;
Получил ошибку
[Pascal Error] Unit1.pas(48): E2003 Undeclared identifier: '_VarFromDynArray'
Из справки прочитал что:
You cannot assign an ordinary static array to a variant. Instead, create a variant array by calling either of the standard functions
Те нужно использовать вариантный массив? А как непонял ведь у меня массив записей....
Все это нужно чтобы клиент мог запросить у COM сервера такой массив..
Kolan (2006-04-07 14:19:00) [1]Так если я передаю параметр как-бы как
varмне надо указать тип VARIANT * или просто VARIANT?
isasa (2006-04-07 13:47:00) [2]Да, FXi в COM сервере это:
TautoFLClass = class(TAutoObject)
...
protected
...
FXi : array of double;
isasa (2006-04-07 13:44:00) [3]Здесь передается массив double, на record сам :), готового кода по рукой нет
На стороне сервера
type
dbuf = array of double;
pdbuf = ^dbuf;
procedure TGases.Set_Xi(Value: OleVariant);
var p : pdbuf;
dataLen : Cardinal;
i : integer;
begin
dataLen:=VarArrayHighBound(Value, VarArrayDimCount(Value));
i:=dataLen div SizeOf(double); //FnComp:=dataLen div SizeOf(double);
SetLength(FXi, i);
p:=VarArrayLock(Value);
for i:=low(FXi) to high(FXi) do FXi[i]:=p^[i]; //move(p^, FXi, dataLen);
VarArrayUnLock(Value);
end;
на стороне клиента
function TForm1.DynArrayToVar(var buf; dataLen: cardinal): variant;
var p : pointer;
begin
Result:=VarArrayCreate([0, dataLen], varByte);
p:=VarArrayLock(Result);
move(buf, p^, dataLen);
VarArrayUnlock(Result);
end;
procedure TForm1.varInterfaceClick(Sender: TObject);
var vrntNature : Variant;
...
begin
...
vrntNature:=CreateOleObject('...'); // или через TLB !
...
vrntNature.Xi:=DynArrayToVar(aXi, (high(aXi)-low(aXi)+1)*SizeOf(double));
...
Kolan (2006-04-07 13:39:00) [4]Уфф. Слишком сложно. Трудно понять....
Сергей М. (2006-04-07 13:36:00) [5]
> Все это нужно чтобы клиент мог запросить у COM сервера такой
> массив
Посмотри как это концептуально делает сам Борланд в методах TDataBlockInterpreter.Read/WriteVariant в модуле sconnect.pas
TDataBlockInterpreter - это как раз класс для маршаллинга/демаршаллинга интерфейсных запросов.
Kolan (2006-04-07 13:35:00) [6]Вроде вот так получилось... Незнаю правильно ли.... Как еще можно?
procedure TForm1.BitBtn1Click(Sender: TObject);
var
V: Variant;
Arr: TDoublePointArray;
I, J: Integer;
begin
SetLength(Arr, 5);
for I:= Low(Arr) to High(Arr) do
begin
Arr[I].X := I;
Arr[I].Y := I * I;
end;
V := VarArrayCreate([0,Length(Arr)*2 - 1],varDouble);
J := 0;
for I:= Low(Arr) to High(Arr) do
begin
V[J] := Arr[I].X;
V[J + 1] := Arr[I].Y;
J := J + 2;
end;
PrintArr(V, 0, Length(Arr)*2 - 1);
end;
procedure TForm1.PrintArr(V: Variant; Left, Right: Integer);
var
I: Integer;
begin
I := VarArrayLowBound(V, 1);
while I <= VarArrayHighBound(V, 1) do
begin
ListBox1.Items.Add('I = ' + FloatToStr(V[I]) + ' - I^2 = ' + FloatToStr(V[I + 1]));
I := I + 2;
end;
end;