Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 передача динамических массивов в параметры метода через Invoke  [new]
Vizit0r
Member

Откуда: Одесса
Сообщений: 678
задача: Вызывать метод по адресу и передавать ему параметры и Result. Разные, от простых типов до рекордов, сетов и прочих. Со всем остальным проблем нет, только с динмассивами - бьюсь со вчера, не выходит каменный цветок.

Подскажите, кто в этом разбирается - как динамические массивы (в чистом виде, не типизированные) ПРАВИЛЬНО передавать?

Сразу уточню, что если прописать TCardArr = array of Cardinal и использовать его - то все красиво, но только такой вариант - это вообще малоинтересно.

procedure _TestM(ObjTypes : array of Word; Colors : array of Word; Cons : array of Cardinal);
begin

end;

class function TSForm.TypeFrom<T>(const Value: T): PTypeInfo;
begin
  Result := System.TypeInfo(T);
end;

procedure TSForm.TestButtonClick(Sender: TObject);
var
  mm,mm2 : array of Word;
  nn  : array of Cardinal;
  Args: TArray<TValue>;
  len : Integer;
  arr : Pointer;
  TInfo : PTypeInfo;
begin
mm := [111,222,333,444];
mm2 := [12,13,14,15];
nn := [555,666,777];

  for I := 0 to 2 do
  begin
    SetLength(Args, Length(Args) + 1);
    //params types taken from script info
    arr := nil;
    case i of
      0 :
      begin
        TInfo := TypeFrom<array of Word>([]);
        len := Length(mm);
        DynArraySetLength(arr, TInfo, 1, @len);
        Move(Pointer(mm)^, arr^, PDynArrayTypeInfo( PByte(TInfo) + PDynArrayTypeInfo(TInfo).name ).elSize * len);
      end;
      1:
      begin
        TInfo := TypeFrom<array of Word>([]);
        len := Length(mm2);
        DynArraySetLength(arr, TInfo, 1, @len);
        Move(Pointer(mm2)^, arr^, PDynArrayTypeInfo( PByte(TInfo) + PDynArrayTypeInfo(TInfo).name ).elSize * len);
      end;
      2:
      begin
        TInfo := TypeFrom<array of Cardinal>([]);
        len := Length(nn);
        DynArraySetLength(arr, TInfo, 1, @len);
        Move(Pointer(nn)^, arr^, PDynArrayTypeInfo( PByte(TInfo) + PDynArrayTypeInfo(TInfo).name ).elSize * len);
      end;
    end;
    Args[i] := TValue.From<Pointer>(Pointer(arr));

    System.Rtti.Invoke(@_TestM,Args,ccReg,nil,False,False);
  end;
end;


Вот максимум чего я добился - на входе в _TestM массив ObjTypes имеет один элемент 111, второй массив nil, третий - мусор.
Данный пример написан для воспроизведения проблемы, в оригинале данные приходят из скрипта, в этом случае и содержимое массивов, и инфа о типе массива и его элементов.

Cмотрел как дельфийский компилятор передает массивы - вроде похоже. Так же копирует массив по указателю.

Сообщение было отредактировано: 6 авг 19, 22:55
6 авг 19, 17:04    [21943123]     Ответить | Цитировать Сообщить модератору
 Re: передача динамических массивов в параметры метода через Invoke  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11263
Args[i] := TValue.From<TArray<Word>>(mm)
6 авг 19, 17:19    [21943140]     Ответить | Цитировать Сообщить модератору
 Re: передача динамических массивов в параметры метода через Invoke  [new]
Vizit0r
Member

Откуда: Одесса
Сообщений: 678
mm и прочие массивы здесь для примера.
из скрипта я получаю указатель на Data и тип массива, там нет готового массива для передачи в TValue.
6 авг 19, 17:26    [21943146]     Ответить | Цитировать Сообщить модератору
 Re: передача динамических массивов в параметры метода через Invoke  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11263
Vizit0r
из скрипта я получаю указатель на Data и тип массива
TValue.Make(Data, TypeInfo, Args[i]);
6 авг 19, 17:44    [21943165]     Ответить | Цитировать Сообщить модератору
 Re: передача динамических массивов в параметры метода через Invoke  [new]
Vizit0r
Member

Откуда: Одесса
Сообщений: 678
_Vasilisk_
Vizit0r
из скрипта я получаю указатель на Data и тип массива
TValue.Make(Data, TypeInfo, Args[i]);

Было, результат тот же.
6 авг 19, 18:32    [21943203]     Ответить | Цитировать Сообщить модератору
 Re: передача динамических массивов в параметры метода через Invoke  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 5341
Vizit0r,
procedure _TestM(ObjTypes : array of Word; Colors : array of Word; Cons : array of Cardinal);

это называется открытый массив, а не динамический
фактически передаётся двумя параметрами: указатель на первый элемент и длина массива
6 авг 19, 19:02    [21943233]     Ответить | Цитировать Сообщить модератору
 Re: передача динамических массивов в параметры метода через Invoke  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11263
Vizit0r
Было, результат тот же.
Как получали TypeInfo? И что у вас за указатель? Потому что у меня в проекте все работает. Я даже использую MakeWithoutCopy.

У вас TValue адекватное получается?
6 авг 19, 19:03    [21943234]     Ответить | Цитировать Сообщить модератору
 Re: передача динамических массивов в параметры метода через Invoke  [new]
Vizit0r
Member

Откуда: Одесса
Сообщений: 678
kealon(Ruslan)
Vizit0r,
procedure _TestM(ObjTypes : array of Word; Colors : array of Word; Cons : array of Cardinal);

это называется открытый массив, а не динамический
фактически передаётся двумя параметрами: указатель на первый элемент и длина массива


огромное спасибо, передача второго параметра полностью решила проблему.

Вот что значит незнание базовых вещей :(
6 авг 19, 19:34    [21943259]     Ответить | Цитировать Сообщить модератору
 Re: передача динамических массивов в параметры метода через Invoke  [new]
Vizit0r
Member

Откуда: Одесса
Сообщений: 678
_Vasilisk_
Vizit0r
Было, результат тот же.
Как получали TypeInfo? И что у вас за указатель? Потому что у меня в проекте все работает. Я даже использую MakeWithoutCopy.

У вас TValue адекватное получается?


TValue адекватное было. Возвращало значения, тип правильный.
Проблема была при передаче параметров из-за передачи 2х параметров, как подсказали выше.
6 авг 19, 19:43    [21943269]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить