powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как объявлена функция Concat
24 сообщений из 24, страница 1 из 1
Как объявлена функция Concat
    #39844330
Ghost Writer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возможно ли сделать свою функцию с синтаксисом, подобным синтаксису функции Concat ?
из справки Delphi 7 Delphi syntax:
Код: pascal
1.
function Concat(s1 [, s2,..., sn]: string): string;


[array of const] не то, тут без скобок []. просто интересно.

скрин из лазаруса
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844357
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, это магия компилятора.

PS: Нет, слабодокументированное слово varargs тут не поможет.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844363
x77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну, можно.

function Concat(s1: string): string; overload;
function Concat(s1, s2: string): string; overload;
function Concat(s1, s2, s3: string): string; overload;
(и тут Остапа понесло...)

все это запихать в отдельный юнит, и дальше, из основной программы, вы сможете вызывать функцию Concat с любім кол-вом параметров, не превішающих те, что вы не поленилилсь прописать в том самом грешном юните.
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844539
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Элитные грабли с доставкой
Код: 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.
program xe2concat;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TRake = function (Count: Integer): string; cdecl varargs;

function Concat(Count: Integer; Params: Pointer): string; cdecl;
var
  Items: array [0..31] of PChar absolute Params;
  Index: Integer;
begin
  Result := '';
  for Index := 0 to Count - 1 do
    Result := Result + Items[Index];
end;

var
  Text: string;
begin
  ReportMemoryLeaksOnShutdown := True;
  try
    Text := TRake(@Concat)(5, 'раз', 'два', 'три', 'пять', 'шесть');
    WriteLn(Text);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.


Только сегодня специальный бонус каждому покупателю: необъятное поле возможностей выстрелить себе в ногу уже в комплекте!
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844546
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ghost Writer,

function Concat(s1: array of string): string;

Concat(['раз','двас', 'стопицот']);
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844556
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wolverinGhost Writer,

function Concat(s1: array of string): string;

Concat(['раз','двас', 'стопицот']);

Вы бы хоть ТС почитали

Ghost Writer [array of const] не то, тут без скобок []. просто интересно.
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844559
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr,

ну я так и подумал - в объявлении без скобок )
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844561
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wolverinDimaBr,
ну я так и подумал - в объявлении без скобок )
И после этого мне кто-то говорит, что другие невнимательно читают.
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844581
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBrИ после этого мне кто-то говорит, что другие невнимательно читают.
разве я сказал что я не другие? ))
да и подобие самое подобное, не обязательно же const, можно же наверное и указатели передать, все лучше чем предложенное alekcvp
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844585
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wolverinвсе лучше чем предложенное
В ТЗ было "без скобок" - я сделал "без скобок", а что ТЗ кривое с точки зрения возможностей языка, так это не ко мне. За что уплочено - то и получено (С)
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844601
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovНет, слабодокументированное слово varargs тут не поможет.Легко! Функцию реализовать на сях (естественно с cdecl), компильнуть в объектный файл и прилинковать к проекту
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844604
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
  TMultiParamAttribute<T> = class(TCustomAttribute)
  protected
    FItems: TArray<T>;
  public
    property Items: TArray<T> read FItems;
    constructor Create(const AParams: array of T); overload;
    constructor Create(const AParam: T); overload;
    constructor Create(const AParam1, AParam2: T); overload;
    constructor Create(const AParam1, AParam2, AParam3: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13,
      AParam14: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13,
      AParam14, AParam15: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13,
      AParam14, AParam15, AParam16: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13,
      AParam14, AParam15, AParam16, AParam17: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13,
      AParam14, AParam15, AParam16, AParam17, AParam18: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13,
      AParam14, AParam15, AParam16, AParam17, AParam18, AParam19: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13,
      AParam14, AParam15, AParam16, AParam17, AParam18, AParam19, AParam20: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13,
      AParam14, AParam15, AParam16, AParam17, AParam18, AParam19, AParam20, AParam21: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13,
      AParam14, AParam15, AParam16, AParam17, AParam18, AParam19, AParam20, AParam21, AParam22: T); overload;
    constructor Create(const AParam1, AParam2, AParam3, AParam4, AParam5, AParam6, AParam7, AParam8, AParam9, AParam10, AParam11, AParam12, AParam13,
      AParam14, AParam15, AParam16, AParam17, AParam18, AParam19, AParam20, AParam21, AParam22, AParam23: T); overload;
  end;
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844649
Ghost Writer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpЭлитные грабли с доставкойколдунство !
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844664
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
Код: pascal
1.
Items: array [0..31] of PChar absolute Params;

заменить на
Код: pascal
1.
Items: array [0..0] of PChar absolute Params;

и добавить
Код: pascal
1.
{$R-}
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844668
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А в Oxygene есть модификатор " params "
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844857
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
отстрелить все насовсем:
Код: 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.
program VarArgs;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils;

type
  TStringFunc= function: string; cdecl varargs;

procedure MyConcat(pResult: pstring); cdecl;
var
  p: ppointer;
  i: integer;
begin
  string(pResult^):='';
  p:=@pResult;
  dec(p); i:=ord(string(p^)[3]) div sizeof(pointer);
  inc(p);
  for i:=2 to i do begin
    inc(p); string(pResult^):=string(pResult^) + string(p^);
  end;
end;

var
  res, s1, s2, s3, s4, s5: string;
begin
  res:='000';
  s1:='1';
  s2:='22';
  s3:='333';
  s4:='4444';
  s5:='55555';
  res:=TStringFunc(@MyConcat)(s1, s2, s3, s4, s5);
  WriteLn(res);
  ReadLn;
end.

...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844864
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
отстрелить не так больно:
Код: 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.
program VarArgs;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils;

type
  TStringFunc= function: string; cdecl varargs;

procedure MyConcat(pResult: pstring); cdecl;
var
  p: ppointer;
  i: integer;
begin
  string(pResult^):='';
  p:=@pResult;
  dec(p); i:=ord(string(p^)[3]) div sizeof(pointer);
  inc(p);
  for i:=2 to i do begin
    inc(p);
    if p^>pchar(nil)+$FFFF then string(pResult^):=string(pResult^) + string(p^)
    else if p^<>nil then string(pResult^):=string(pResult^) + pchar(p);
  end;
end;

var
  res, s2, s4: string;
begin
  res:='000';
  s2:='22';
  s4:='4444';
  res:=TStringFunc(@MyConcat)('1', s2, '333', s4, '', '55555');
  WriteLn(res);
  ReadLn;
end.

...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844904
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
немного упростил, но по-прежнему pchar требуется вручную конвертировать в string перед вызовом,
a конкатенация с символом #0 не изменяет результат, т.к. этот случай не отличим от пустой строки:
Код: 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.
program VarArgs;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils;

type
  TStringFunc= function: string; cdecl varargs;

procedure MyConcat(pResult: pstring); cdecl;
var
  p: ppointer;
  i: integer;
begin
  pResult^:='';
  p:=@pResult;
  dec(p); i:=ord(string(p^)[3]) div sizeof(pointer);
  inc(p);
  for i:=2 to i do begin
    inc(p);
    if p^>pchar(nil)+$FFFF then pResult^:=pResult^ + string(p^)
    else if p^<>nil        then pResult^:=pResult^ + pchar(p)[0];
  end;
end;

const
  pch: pchar='pch';
var
  res, s0, s2, s4: string;
begin
  res:='000';
  s0:=#0;
  s2:='22';
  s4:='4444';
  res:=TStringFunc(@MyConcat)(string(pch), '1', #0, s2, '333', s0, s4, '', '55555');  //res='pch122333'#0'444455555'
  WriteLn(res);
  ReadLn;
end.

...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844929
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

А как количество параметров узнаётся?..
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844937
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpА как количество параметров узнаётся?..

По размеру памяти, выделенной для них на стеке.
Сразу после вызова функции следует инструкция
add esp, size
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39844968
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
теперь с любым числом параметров
Код: 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.
program VarArgs;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils;

type
  TStringFunc= function: string; cdecl varargs;

//pchar требуется вручную конвертировать в string перед вызовом,
//конкатенация с символом #0 не изменяет результат, т.к. этот случай не отличим от пустой строки
procedure MyConcat(pResult: pstring); cdecl;
var
  p: ppointer;    
  i: integer;
begin
  pResult^:='';
  p:=@pResult;
  dec(p);
  case pword(p^)^ of
    $c481: i:=pinteger(pchar(p^)+2)^;  //более 31 параметра, включая результат
    $c483: i:=pbyte(pchar(p^)+2)^;     //не более 31 параметра, включая результат
    else   i:=sizeof(pointer);         //не найдена интструкция add esp,size (передан только результат)
  end;
  inc(p);
  for i:=2 to i div sizeof(pointer) do begin
    inc(p);
    if p^>pchar(nil)+$FFFF then pResult^:=pResult^ + string(p^)
    else if p^<>nil        then pResult^:=pResult^ + pchar(p)[0];
  end;
end;

const
  pch: pchar='pch';
var
  res, s0, s2, s4: string;
begin
  res:='000';
  s0:=#0;
  s2:='22';
  s4:='4444';
  res:=TStringFunc(@MyConcat)(string(pch), '1', #0, s2, '333', s0, s4, '', '55555');  //res='pch122333'#0'444455555'
  WriteLn(res);
  res:=TStringFunc(@MyConcat)(string(pch), '1', #0, s2, '333', s0, s4, '', '55555'
  , '1', #0, s2, '333', s0, s4, '', '55555'
  , '1', #0, s2, '333', s0, s4, '', '55555'
  , '1', #0, s2, '333', s0, s4, '', '55555'
  );
  WriteLn(res);
  res:=TStringFunc(@MyConcat);
  WriteLn(res);
  ReadLn;
end.

...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39845170
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

$c481 - это опкод add esp, ... что-ли? p^ - это указатель на адрес возврата в стеке?..
А pdword(p^)^ - первая команда после возврата?..
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39845251
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

для fpc ещё можно c export name в реализации и external в декларации поиграться, тогда явное приведение функции не потребуется
...
Рейтинг: 0 / 0
Как объявлена функция Concat
    #39845292
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpAleksandr Sharahov,

$c481 - это опкод add esp, ... что-ли? p^ - это указатель на адрес возврата в стеке?..
А pdword(p^)^ - первая команда после возврата?..

да
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как объявлена функция Concat
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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