Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / передача динамических массивов в параметры метода через Invoke / 9 сообщений из 9, страница 1 из 1
06.08.2019, 17:04
    #39845975
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача динамических массивов в параметры метода через Invoke
задача: Вызывать метод по адресу и передавать ему параметры и Result. Разные, от простых типов до рекордов, сетов и прочих. Со всем остальным проблем нет, только с динмассивами - бьюсь со вчера, не выходит каменный цветок.

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

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

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
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мотрел как дельфийский компилятор передает массивы - вроде похоже. Так же копирует массив по указателю.
...
Рейтинг: 0 / 0
06.08.2019, 17:19
    #39845987
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача динамических массивов в параметры метода через Invoke
Код: pascal
1.
Args[i] := TValue.From<TArray<Word>>(mm)
...
Рейтинг: 0 / 0
06.08.2019, 17:26
    #39845992
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача динамических массивов в параметры метода через Invoke
mm и прочие массивы здесь для примера.
из скрипта я получаю указатель на Data и тип массива, там нет готового массива для передачи в TValue.
...
Рейтинг: 0 / 0
06.08.2019, 17:44
    #39846000
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача динамических массивов в параметры метода через Invoke
Vizit0rиз скрипта я получаю указатель на Data и тип массива
Код: pascal
1.
TValue.Make(Data, TypeInfo, Args[i]);
...
Рейтинг: 0 / 0
06.08.2019, 18:32
    #39846023
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача динамических массивов в параметры метода через Invoke
_Vasilisk_Vizit0rиз скрипта я получаю указатель на Data и тип массива
Код: pascal
1.
TValue.Make(Data, TypeInfo, Args[i]);


Было, результат тот же.
...
Рейтинг: 0 / 0
06.08.2019, 19:02
    #39846044
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача динамических массивов в параметры метода через Invoke
Vizit0r,
Код: pascal
1.
procedure _TestM(ObjTypes : array of Word; Colors : array of Word; Cons : array of Cardinal);


это называется открытый массив , а не динамический
фактически передаётся двумя параметрами: указатель на первый элемент и длина массива
...
Рейтинг: 0 / 0
06.08.2019, 19:03
    #39846045
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача динамических массивов в параметры метода через Invoke
Vizit0rБыло, результат тот же.Как получали TypeInfo? И что у вас за указатель? Потому что у меня в проекте все работает. Я даже использую MakeWithoutCopy.

У вас TValue адекватное получается?
...
Рейтинг: 0 / 0
06.08.2019, 19:34
    #39846060
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача динамических массивов в параметры метода через Invoke
kealon(Ruslan)Vizit0r,
Код: pascal
1.
procedure _TestM(ObjTypes : array of Word; Colors : array of Word; Cons : array of Cardinal);


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

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

Вот что значит незнание базовых вещей :(
...
Рейтинг: 0 / 0
06.08.2019, 19:43
    #39846067
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача динамических массивов в параметры метода через Invoke
_Vasilisk_Vizit0rБыло, результат тот же.Как получали TypeInfo? И что у вас за указатель? Потому что у меня в проекте все работает. Я даже использую MakeWithoutCopy.

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

TValue адекватное было. Возвращало значения, тип правильный.
Проблема была при передаче параметров из-за передачи 2х параметров, как подсказали выше.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / передача динамических массивов в параметры метода через Invoke / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]