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


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

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

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

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

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

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

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

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

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

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

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

ну я так и подумал - в объявлении без скобок )
...
Рейтинг: 0 / 0
02.08.2019, 12:26
    #39844561
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
wolverinDimaBr,
ну я так и подумал - в объявлении без скобок )
И после этого мне кто-то говорит, что другие невнимательно читают.
...
Рейтинг: 0 / 0
02.08.2019, 12:47
    #39844581
wolverin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
DimaBrИ после этого мне кто-то говорит, что другие невнимательно читают.
разве я сказал что я не другие? ))
да и подобие самое подобное, не обязательно же const, можно же наверное и указатели передать, все лучше чем предложенное alekcvp
...
Рейтинг: 0 / 0
02.08.2019, 12:50
    #39844585
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
wolverinвсе лучше чем предложенное
В ТЗ было "без скобок" - я сделал "без скобок", а что ТЗ кривое с точки зрения возможностей языка, так это не ко мне. За что уплочено - то и получено (С)
...
Рейтинг: 0 / 0
02.08.2019, 13:11
    #39844601
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
Dimitry SibiryakovНет, слабодокументированное слово varargs тут не поможет.Легко! Функцию реализовать на сях (естественно с cdecl), компильнуть в объектный файл и прилинковать к проекту
...
Рейтинг: 0 / 0
02.08.2019, 13:13
    #39844604
Michael Longneck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
Код: 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
02.08.2019, 14:50
    #39844649
Ghost Writer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
alekcvpЭлитные грабли с доставкойколдунство !
...
Рейтинг: 0 / 0
02.08.2019, 15:12
    #39844664
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
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
02.08.2019, 15:14
    #39844668
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
А в Oxygene есть модификатор " params "
...
Рейтинг: 0 / 0
02.08.2019, 22:10
    #39844857
Aleksandr Sharahov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
отстрелить все насовсем:
Код: 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
02.08.2019, 23:13
    #39844864
Aleksandr Sharahov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
отстрелить не так больно:
Код: 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
03.08.2019, 10:56
    #39844904
Aleksandr Sharahov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
немного упростил, но по-прежнему 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
03.08.2019, 14:25
    #39844929
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как объявлена функция Concat
Aleksandr Sharahov,

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

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

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

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

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

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


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