Ответ 1
Вы пытаетесь использовать версию переменных параметра AsyncCall
. В коде говорится, что поддерживаются следующие типы:
Supported types: Integer : Arg: Integer Boolean : Arg: Boolean Char : Arg: AnsiChar WideChar : Arg: WideChar Int64 : [const] Arg: Int64 Extended : [const] Arg: Extended Currency : [const] Arg: Currency String : [const] Arg: ShortString Pointer : [const] Arg: Pointer PChar : [const] Arg: PChar Object : [const] Arg: TObject Class : [const] Arg: TClass AnsiString : [const] Arg: AnsiString UnicodeString: [const] Arg: UnicodeString PWideChar : [const] Arg: PWideChar WideString : [const] Arg: WideString Interface : [const] Arg: IInterface Variant : const Arg: Variant
Ваша функция получает параметр открытого массива и параметр var
, который не может быть найден в списке выше. Более того, функция должна использовать соглашение о вызове cdecl
.
Вот версия вашего кода, которая работает:
program Test;
{$APPTYPE CONSOLE}
uses
SysUtils,
Math,
AsyncCalls in 'AsyncCalls.pas';
var
arr: array of integer;
procedure GetMax(left, right: integer; max: PInteger); cdecl;
var
i: integer;
begin
max^ := arr[left];
for i := left + 1 to right do
begin
if (arr[i] > max^) then
begin
max^ := arr[i];
end;
end;
end;
const
N = 100000;
var
a, b: IAsyncCall;
i, maxv, max1, max2: integer;
begin
SetLength(arr, N);
maxv := -1;
for i := 0 to High(arr) do
begin
arr[i] := RandomRange(0, MaxInt);
if (arr[i] > maxv) then
begin
maxv := arr[i];
end;
end;
a := AsyncCall(@GetMax, [0, Length(arr) div 2, @max1]);
b := AsyncCall(@GetMax, [(Length(arr) div 2) + 1, High(arr), @max2]);
AsyncMultiSync([a, b], True, INFINITE);
Writeln(max1, ', ', max2, ', ', Max(max1, max2));
Writeln(maxv);
Readln;
end.
Обратите внимание, что я внесла следующие изменения:
- Удалено использование
Forms
и вызовProcessMessages
. - Сделано
GetMax
используйте соглашение о вызовеcdecl
. - Передать
max
как указатель на целое число, а не на параметрvar
. Это связано с тем, что параметрыvar
не поддерживаются. - Пусть
GetMax
использует глобальную переменнуюarr
, а не принимает ее как параметр. Это было для целесообразности. Альтернативой может быть передача адреса первого элемента.
Честно говоря, ваш код достаточно сложный, чтобы переменный параметр AsyncCall
чувствовал себя немного растянутым. Возможно, вам лучше передать объект или указатель на запись, а не перегружать переменные.
Я должен также указать, что AsyncCalls больше не разрабатывается. Вы, на мой взгляд, лучше обслуживали бы, принимая OTL, чем AsyncCalls.