Здравствуйте, 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;
Имеется СОМ сервер написанный на Дельфи, нужно передать массив данных, состоящий из чисел и строк, с числами проблем нет, чтобы передать строки напрашивается что массив должен быть 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;
при пошаговой отладке все в норме, значение '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?
Если массив вариантов, то
D> IntArray: array[0..9] of OleVariant;
и этот массив тоже должен быть массив вариантов.
D> Result := VarArrayCreate([0, SizeOf(IntArray) — 1], varByte);
... D> Move(IntArray, PData^, SizeOf(IntArray));
GS
Re[2]: Маршалинг: передача в массиве строк и чисел
Здравствуйте, 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]: Маршалинг: передача в массиве строк и чисел
Здравствуйте, 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. Типы должны совпадать.
Я не точно знаю Паскаль, но копирование строк осуществляется не так. Для чисел проходит, для строк нет. Ибо существует деструктор OleVariant, который разрушает строку при выходе из подпрограммы. Нужно копировать поэлементно.
D>Почему она вознивает, если OleVariant позволяет передавать данные WideString?
Позволяет. Но тебе нужно добиться неразрушения строки в деструкторе OleVariant.
Vi2>Я не точно знаю Паскаль, но копирование строк осуществляется не так. Для чисел проходит, для строк нет. Ибо существует деструктор OleVariant, который разрушает строку при выходе из подпрограммы. Нужно копировать поэлементно.
Поэлементно, это подразумевается тип char, то есть создавать массив из символов, я правильно понял?
Vi2>
D>>Почему она вознивает, если OleVariant позволяет передавать данные WideString?
Vi2>Позволяет. Но тебе нужно добиться неразрушения строки в деструкторе OleVariant.
Re[4]: Маршалинг: передача в массиве строк и чисел
Здравствуйте, 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;
Я так понимаю типы совпадают, при попытке создать массив получаем "Could not convert variant of type (Array variant) into type (OleStr)". Вопрос, так какого типа должен быть создаваемый массив и IntArray?
Здравствуйте, 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 или системной функции копирования Вариантов.
Здравствуйте, 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>