Re: Маршалинг: передача в массиве строк и чисел
От: manumba  
Дата: 21.03.03 08:06
Оценка: 8 (1)
Здравствуйте, dikma, Вы писали:

D>Имеется СОМ сервер написанный на Дельфи, нужно передать массив данных, состоящий из чисел и строк, с числами проблем нет, чтобы передать строки напрашивается что массив должен быть WideString. А как совместить в одном масиве строки и числа? Пробывал OleVariant, не получилось.


D>function TServerDM.GetArray: OleVariant;

D>var
D> IntArray: array[0..9] of OleVariant;
D> I: Integer;
D> PData: PVariant;
D> VStr: OleVariant;
D>begin
D> for I := 0 to 8 do
D> begin
D> IntArray[I] := I;
D> end;
D> VStr := '123';
D> IntArray[9] := VStr;

D> Result := VarArrayCreate([0, SizeOf(IntArray) — 1], varByte);

D> PData := VarArrayLock(Result);
D> try
D> Move(IntArray, PData^, SizeOf(IntArray));
D> finally
D> VarArrayUnlock(Result);
D> end;
D>end;

D>при пошаговой отладке все в норме, значение '123' есть в массиве


D>procedure TMain.GetArrayFromServer;

D>var
D> IntArray: array[0..9] of OleVariant;
D> VStr: OleVariant;
D> VData: OleVariant;
D> PData: PVariant;
D> I: Integer;
D>begin
D> VData := ServerDM.GetArray;
D> PData := VarArrayLock(VData);
D> try
D> Move(PData^, IntArray, SizeOf(IntArray));
D> finally
D> VarArrayUnlock(VData);
D> end;
D> for I := 0 to 8 do
D> begin
D> ArrayMemo.Lines.Add(IntToStr(IntArray[I]));
D> end;
D> VStr := IntArray[9];
D> ^^^^^^^^^^ значение не определено, здесь появляется ошибка.
D>end;

D>Почему она вознивает, если OleVariant позволяет передавать данные WideString?


Не знаю почему эта ошибка возникает, но зачем так все сложно?
Я делаю чуть иначе и у меня все работает....вот мой код:

function TServerDM.GetArray: OleVariant;
var
  AParams: OleVariant;
  i: integer;
begin
  AParams:=VarArrayCreate([0,9],varVariant);
  for i:=0 to 8 do AParams[i]:=i;
  
  AParams[9]:='string value';

  Result:=AParams;
end;


procedure TMain.GetArrayFromServer;
var
  VData: OleVariant;
  VStr : OleVariant;
  I: Integer;  
begin
  VData := ServerDM.GetArray;
  if not VarIsEmpty(VData) then begin
     for I := 0 to 8 do begin    
        ArrayMemo.Lines.Add(IntToStr(IntArray[I]));  
     end;
     VStr := IntArray[9];
  end;
end;
... << RSDN@Home 1.0 beta 6a >>
Маршалинг: передача в массиве строк и чисел
От: dikma  
Дата: 20.03.03 16:01
Оценка:
Имеется СОМ сервер написанный на Дельфи, нужно передать массив данных, состоящий из чисел и строк, с числами проблем нет, чтобы передать строки напрашивается что массив должен быть WideString. А как совместить в одном масиве строки и числа? Пробывал OleVariant, не получилось.

function TServerDM.GetArray: OleVariant;
var
IntArray: array[0..9] of OleVariant;
I: Integer;
PData: PVariant;
VStr: OleVariant;
begin
for I := 0 to 8 do
begin
IntArray[I] := I;
end;
VStr := '123';
IntArray[9] := VStr;

Result := VarArrayCreate([0, SizeOf(IntArray) — 1], varByte);
PData := VarArrayLock(Result);
try
Move(IntArray, PData^, SizeOf(IntArray));
finally
VarArrayUnlock(Result);
end;
end;

при пошаговой отладке все в норме, значение '123' есть в массиве

procedure TMain.GetArrayFromServer;
var
IntArray: array[0..9] of OleVariant;
VStr: OleVariant;
VData: OleVariant;
PData: PVariant;
I: Integer;
begin
VData := ServerDM.GetArray;
PData := VarArrayLock(VData);
try
Move(PData^, IntArray, SizeOf(IntArray));
finally
VarArrayUnlock(VData);
end;
for I := 0 to 8 do
begin
ArrayMemo.Lines.Add(IntToStr(IntArray[I]));
end;
VStr := IntArray[9];
^^^^^^^^^^ значение не определено, здесь появляется ошибка.
end;

Почему она вознивает, если OleVariant позволяет передавать данные WideString?
Re: Маршалинг: передача в массиве строк и чисел
От: George Seryakov Россия  
Дата: 20.03.03 16:09
Оценка:
Здравствуйте, dikma, Вы писали:

Если массив вариантов, то

D> IntArray: array[0..9] of OleVariant;


и этот массив тоже должен быть массив вариантов.

D> Result := VarArrayCreate([0, SizeOf(IntArray) — 1], varByte);

...
D> Move(IntArray, PData^, SizeOf(IntArray));
GS
Re[2]: Маршалинг: передача в массиве строк и чисел
От: dikma  
Дата: 20.03.03 16:25
Оценка:
Здравствуйте, George Seryakov, Вы писали:

GS>Здравствуйте, dikma, Вы писали:


GS>Если массив вариантов, то


D>> IntArray: array[0..9] of OleVariant;


GS>и этот массив тоже должен быть массив вариантов.


D>> Result := VarArrayCreate([0, SizeOf(IntArray) — 1], varByte);

^^^^^^^ этот массив?
уточните пожалуйста какой.
GS>...
D>> Move(IntArray, PData^, SizeOf(IntArray));
Re[3]: Маршалинг: передача в массиве строк и чисел
От: George Seryakov Россия  
Дата: 20.03.03 16:29
Оценка:
Здравствуйте, dikma, Вы писали:

GS>>Если массив вариантов, то


D>>> IntArray: array[0..9] of OleVariant;


GS>>и этот массив тоже должен быть массив вариантов.


D>>> Result := VarArrayCreate([0, SizeOf(IntArray) — 1], varByte);

D> ^^^^^^^ этот массив?
D>уточните пожалуйста какой.
GS>>...
D>>> Move(IntArray, PData^, SizeOf(IntArray));

Ты создаешь массив Result (VarArray, что SAFEARRAY, полагаю), определяешь его как массив varByte. Далее ты берешь масив OleVariant (обычный) и бинарно копируешь его в секцию данных массива Result. Типы должны совпадать.
GS
Re: Копирование строки в массив
От: Vi2 Удмуртия http://www.adem.ru
Дата: 21.03.03 04:38
Оценка:
Здравствуйте, dikma, Вы писали:

D> Result := VarArrayCreate([0, SizeOf(IntArray) — 1], varByte);

Насколько верно varByte. Result должен быть массивом с типом данных Variant (VT_VARIANT).

D> PData := VarArrayLock(Result);
D> try
D> Move(IntArray, PData^, SizeOf(IntArray));

Я не точно знаю Паскаль, но копирование строк осуществляется не так. Для чисел проходит, для строк нет. Ибо существует деструктор OleVariant, который разрушает строку при выходе из подпрограммы. Нужно копировать поэлементно.

D>Почему она вознивает, если OleVariant позволяет передавать данные WideString?

Позволяет. Но тебе нужно добиться неразрушения строки в деструкторе OleVariant.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Копирование строки в массив
От: dikma  
Дата: 21.03.03 06:32
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, dikma, Вы писали:


Vi2>

D>> Result := VarArrayCreate([0, SizeOf(IntArray) — 1], varByte);

Vi2>Насколько верно varByte. Result должен быть массивом с типом данных Variant (VT_VARIANT).

Vi2>

D>> PData := VarArrayLock(Result);
D>> try
D>> Move(IntArray, PData^, SizeOf(IntArray));

Vi2>Я не точно знаю Паскаль, но копирование строк осуществляется не так. Для чисел проходит, для строк нет. Ибо существует деструктор OleVariant, который разрушает строку при выходе из подпрограммы. Нужно копировать поэлементно.
Поэлементно, это подразумевается тип char, то есть создавать массив из символов, я правильно понял?

Vi2>

D>>Почему она вознивает, если OleVariant позволяет передавать данные WideString?

Vi2>Позволяет. Но тебе нужно добиться неразрушения строки в деструкторе OleVariant.
Re[4]: Маршалинг: передача в массиве строк и чисел
От: dikma  
Дата: 21.03.03 07:05
Оценка:
Здравствуйте, George Seryakov, Вы писали:

GS>Здравствуйте, dikma, Вы писали:


GS>>>Если массив вариантов, то


D>>>> IntArray: array[0..9] of OleVariant;


GS>>>и этот массив тоже должен быть массив вариантов.


D>>>> Result := VarArrayCreate([0, SizeOf(IntArray) — 1], varByte);

D>> ^^^^^^^ этот массив?
D>>уточните пожалуйста какой.
GS>>>...
D>>>> Move(IntArray, PData^, SizeOf(IntArray));

GS>Ты создаешь массив Result (VarArray, что SAFEARRAY, полагаю), определяешь его как массив varByte. Далее ты берешь масив OleVariant (обычный) и бинарно копируешь его в секцию данных массива Result. Типы должны совпадать.


Тогда вопрос еще более конкретнее, может чего я не недопонимаю, но...

var
IntArray: array[0..9] of OleVariant;
I: Integer;
PData: PVariant;

begin
for I := 0 to 9 do
begin
IntArray[I] := 'a';
end;

Result := VarArrayCreate([0, SizeOf(IntArray) — 1], varVariant);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PData := VarArrayLock(Result);
try
Move(IntArray, PData^, SizeOf(IntArray));
finally
VarArrayUnlock(Result);
end;

Я так понимаю типы совпадают, при попытке создать массив получаем "Could not convert variant of type (Array variant) into type (OleStr)". Вопрос, так какого типа должен быть создаваемый массив и IntArray?
Re[3]: Копирование строки в массив
От: Vi2 Удмуртия http://www.adem.ru
Дата: 21.03.03 07:10
Оценка:
Здравствуйте, dikma, Вы писали:

Vi2>>Я не точно знаю Паскаль, но копирование строк осуществляется не так. Для чисел проходит, для строк нет. Ибо существует деструктор OleVariant, который разрушает строку при выходе из подпрограммы. Нужно копировать поэлементно.


D>Поэлементно, это подразумевается тип char, то есть создавать массив из символов, я правильно понял?

Нет. Что-то подобное на С
for( int i = 0; i < max; i++ )
  PData[i] = IntArray[i]; 
или
for( int i = 0; i < max; i++ )
  ::VariantCopy( PData[i], IntArray[i] );

с использованием оператора копирования из OleVariant или системной функции копирования Вариантов.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Маршалинг: передача в массиве строк и чисел
От: dikma  
Дата: 21.03.03 08:15
Оценка:
Здравствуйте, manumba, Вы писали:

M>Здравствуйте, dikma, Вы писали:


M>Не знаю почему эта ошибка возникает, но зачем так все сложно?

M>Я делаю чуть иначе и у меня все работает....вот мой код:
Большое спасибо!!!


M>
M>function TServerDM.GetArray: OleVariant;
M>var
M>  AParams: OleVariant;
M>  i: integer;
M>begin
M>  AParams:=VarArrayCreate([0,9],varVariant);
M>  for i:=0 to 8 do AParams[i]:=i;
M>  
M>  AParams[9]:='string value';

M>  Result:=AParams;
M>end;
M>


M>
M>procedure TMain.GetArrayFromServer;
M>var
M>  VData: OleVariant;
M>  VStr : OleVariant;
M>  I: Integer;  
M>begin
M>  VData := ServerDM.GetArray;
M>  if not VarIsEmpty(VData) then begin
M>     for I := 0 to 8 do begin    
M>        ArrayMemo.Lines.Add(IntToStr(IntArray[I]));  
M>     end;
M>     VStr := IntArray[9];
M>  end;
M>end;
M>


M>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.