Delphi в стиле Си

Тема в разделе "DELPHI", создана пользователем Intro, 15 май 2019.

  1. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    601
    Может кому то понадобиться. Программирования в делфи консольных приложений в стиле C.
    Стартовый код располагается в файле имя_проекта.dpr
    Код (Pascal):
    1. program nameproject;
    2. {
    3.    Консольное приложения в стиле Си для Win32
    4. }
    5. {$APPTYPE CONSOLE}
    6. uses
    7.   Windows,
    8.   name_project in 'name_project.pas';
    9.   procedure __getmainargs(_argc: PInteger; _argv, _environ:PChar; _param:integer; _si:PStartupInfo); cdecl; external 'msvcrt.dll';
    10. //СТАРТОВЫЙ КОД
    11. var   argc:integer;
    12.    argv, environ : arrayPChar;
    13.    _si:STARTUPINFO;
    14. begin
    15.    _si.cb := sizeof(STARTUPINFO);
    16.    GetStartupInfoA( _si );
    17.    __getmainargs( @argc, @argv, @environ, 0, @_si );
    18.    ExitProcess(main(argc, argv, environ));
    19. end.
    А теперь код проекта.
    Код (Pascal):
    1. unit name_project;
    2.  
    3. interface
    4.  
    5. uses
    6.    Windows{, SysUtils};
    7.  
    8. type   arrayPChar = array of PChar;
    9.      ParrayPChar = ^arrayPChar;
    10.  
    11.    function printf(Format: PChar): Integer; cdecl; varargs; external 'msvcrt.dll';
    12.    function sprintf(CharBuf: PChar; const Format: PAnsiChar): Integer; cdecl; varargs; external 'msvcrt.dll';
    13.    function main(argc : integer; argv, envp : arrayPChar): Integer; cdecl;
    14.  
    15. implementation
    16.  
    17. function main(argc : integer; argv, envp : arrayPChar): Integer;
    18. var   i : integer;
    19. begin
    20.    printf('ParamCount: %d'#10, argc);
    21.    for i:=0 to argc-1 do
    22.      printf('argv[%d]=[%s]'#10, i, argv[i]);
    23. end;
    24. end.
    Как то так, стартовый код в принципе надо переделать, но пока что есть.
    PS
    Код переделал, на более компактный и главное рабочий.
     
    Последнее редактирование: 16 май 2019
    CaptainObvious и CKAP нравится это.
  2. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    601
    Да, надо привести более реальный пример.
    Я тут намедни выложил код для расчёта даты пасхи. Попробуем сделать тоже на паскале в стиле Си, т.е. используем стандартную библиотеку С.
    Стартовый код.
    Код (Pascal):
    1. program easter_project;
    2. {
    3.    Консольное приложения в стиле Си для Win32
    4. }
    5. {$APPTYPE CONSOLE}
    6. uses
    7.   Windows,
    8.   easter in 'easter.pas';
    9.   procedure __getmainargs(_argc: PInteger; _argv, _environ:PChar; _param:integer; _si:PStartupInfo); cdecl; external 'msvcrt.dll';
    10. //СТАРТОВЫЙ КОД
    11. var   argc:integer;
    12.    argv, environ : arrayPChar;
    13.    _si:STARTUPINFO;
    14. begin
    15.    _si.cb := sizeof(STARTUPINFO);
    16.    GetStartupInfoA( _si );
    17.    __getmainargs( @argc, @argv, @environ, 0, @_si );
    18.    ExitProcess(main(argc, argv, environ))
    19. end.
    20.  
    Основной код
    Код (Pascal):
    1. {=====================================================
    2. Дата православной и католической пасхи.
    3. По формуле Карла Фридриха Гаусса (1777-1855).
    4. Календарь и хронология. Климишин И.А. 1990, стр. 133
    5. (c) Intro  v1.03   5.04.2019     25.05.2019
    6. ======================================================}
    7. unit easter;
    8. interface
    9.  
    10. uses Windows;
    11.  
    12. type   arrayPChar = array of PChar;
    13.      ParrayPChar = ^arrayPChar;
    14.   Sdate = record
    15.        day:byte;   // 1-31
    16.        mon:byte;   // 0-11
    17.      end;
    18.  
    19.    function printf(Format: PChar): Integer; cdecl; varargs; external 'msvcrt.dll';
    20.    function sprintf(CharBuf: PChar; const Format: PAnsiChar): Integer; cdecl; varargs; external 'msvcrt.dll';
    21.    function atoi(_Str: PChar): Integer; cdecl; external 'msvcrt.dll';
    22.    function main(argc : integer; argv, envp : arrayPChar): Integer; cdecl;
    23.  
    24. implementation
    25. //******************************************
    26.  
    27. function   NewStyleDay(year:integer):integer;   // Расхождение между новым и старым стилем, дней.
    28. var century:integer;
    29. begin
    30.    century := year div 100;
    31.    Result := (century div 4)*3 + century mod 4 - 2;
    32. end;
    33.  
    34. function   NumDay2Data(day:integer):Sdate;     // номер дня от 1 марта в дату
    35. var   mon:integer;
    36. begin
    37.    mon := 2;       // March
    38.    if day>31 then
    39.    begin
    40.      dec(day, 31);
    41.      inc(mon);     // April
    42.      if day>30 then
    43.      begin
    44.        dec(day, 30);
    45.        inc(mon)   // May
    46.      end;
    47.    end;
    48.    Result.day := day;
    49.    Result.mon := mon;
    50. end;
    51.  
    52. function   GetEasterGauss(year, m, n:integer; is_catholic:boolean):integer;
    53. var   a,b,c,d,e,day:integer;
    54. begin
    55.    a := year mod 19;
    56.    b := year mod 4;
    57.    c := year mod 7;
    58.    d := (19*a + m) mod 30;
    59.    e := (2*b + 4*c + 6*d + n) mod 7;
    60.    day := 22 + d + e;
    61.    if is_catholic and (day>=56) and (e=6) then dec(day, 7);
    62.    Result:= day;
    63. end;
    64.  
    65. function   GetOrthodoxEaster(year:integer):integer;     // православная пасха
    66. begin
    67.    Result:= GetEasterGauss(year, 15, 6, false);
    68. end;
    69.  
    70. function   GetCatholicEaster(year:integer):integer;     // католическая пасха
    71. var   m,n,p,q,century:integer;
    72. begin
    73.    century := year div 100;
    74.    p := (century*8 + 13) div 25;
    75.    q := century div 4;
    76.    m := (century - p - q + 15) mod 30;
    77.    n := (century - q + 4) mod 7;
    78.    Result:= GetEasterGauss(year, m, n, true);
    79. end;
    80.  
    81. function main(argc : integer; argv, envp : arrayPChar): Integer;
    82. var   year, day : integer;
    83.    old_s, new_s:Sdate;
    84. begin
    85.    Result:=0;
    86.   if argc<>2 then
    87.   begin
    88.      printf('Usage: easter year'#10);
    89.   exit;
    90.    end;
    91.    year := atoi(argv[1]);
    92.   day := GetOrthodoxEaster(year);   // old style
    93.    old_s := NumDay2Data(day);
    94.    inc(day, NewStyleDay(year));
    95.    new_s := NumDay2Data(day);
    96.    printf('Orthodox easter in %d:'#10, year);
    97.    printf('Old style: %2d.%02d New style: %2d.%02d'#10, old_s.day, old_s.mon+1, new_s.day, new_s.mon+1);
    98.    day := GetCatholicEaster(year);   // new style
    99.    new_s := NumDay2Data(day);
    100.    dec(day, NewStyleDay(year));
    101.    old_s := NumDay2Data(day);
    102.    printf('Catholic easter in %d:'#10, year);
    103.    printf('Old style: %2d.%02d New style: %2d.%02d'#10, old_s.day, old_s.mon+1, new_s.day, new_s.mon+1);
    104. end;
    105. end.
    Имеет ли смысл портировать стандартную библиотеку Си в паскаль? Да имеет, хотя компилятор делфи давно устарел. Но всё же код на паскале однозначно более понятен. Да, паскаль плох по сравнения с Си тем, что он просто не доделан как надо.
    Я так думаю.
    ЗЫ
    Я исправил ошибку в коде, где, например для 1991 дата пасхи рассчитывалась не правильно.
    ЗЫЫ
    У меня на делфи 6 получился файл 15К не плохо, GCC создал более объёмный код, даже с ключами оптимизации на минимальный размер.
     
    Последнее редактирование: 27 май 2019
    CKAP нравится это.
  3. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    "более" -- это сколько?
    http://alignment.hep.brandeis.edu/Software/Pascal/Pascal.html а этот пробовал?
    --- Сообщение объединено, 27 май 2019 ---
    https://rextester.com/l/pascal_online_compiler
     
  4. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    лол! паскаль плох по сравнению с си? наверно строгой типизацией? или наличием строкового типа данных? или отсутствием неопределенного поведения? а может быть быстрой скоростью компиляции и нормальной системой модулей? или наличием обработки исключений и ооп?
     
  5. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    в паскаль можно выбросить стандартную либу? Т.е. чтобы был чистый код, как в Си с nodefaultlib ?
     
  6. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Можно. У Ms-Rem'а были статьи по пересборке System.pas и SysInit.pas. Подкладываешь их в свой проект и на выходе получаешь чрезвычайно минималистичный бинарник безо всего.
    --- Сообщение объединено, 28 май 2019 ---
    Так какой смысл? В дэльфи прекрасная RTL из коробки, имхо, намного более удобная, чем CRT.
     
    M0rg0t нравится это.
  7. X-Shar

    X-Shar Active Member

    Публикаций:
    0
    Регистрация:
    24 фев 2017
    Сообщения:
    354
    Может непонял смысл темы ?

    Какой смысл делать Делфи в стиле Си, не лучше тогда и писать на Си ?

    Вообще настольгия, с Делфи начинал, но нравилась 6-ая версия, Borland, потом когда она стала Embarcadero, быстренько перешел на другие среды.)))
     
  8. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Для фронтенда дэльфи и в 2019м остаётся очень вкусным решением! Ничего удобнее FireMonkey ещё не видел, Qt и рядом не стоит по скорости дизайнинга и удобству. И компилятор создаёт неплохой код. Не уровень gcc/msvc/icc, конечно, но уверенный середнячок - для фронтенда хватает с головой.

    Так что, дэльфи жил, жив и будет жить :yes4:
     
  9. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    Есть C++ Builder , который почему-то мало кто юзает. А ведь это все тот же визуальный дельфи, но пишешь на Си. Для гуев лучше нету.
     
  10. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    А с этим не соглашусь. В билдере "плохой" си, не соответствующий никаким стандартам. Помню, когда пробовал на нём писать, были какие-то проблемы с лямбдами и с чем-то ещё, а в LLVM-версии отваливаются подсказки. В общем, билдер оставил смешанные чувства. Проверял год назад, сейчас, возможно, уже исправили - особенно, учитывая, что в одном из недавних обновлений сделали, наконец, поддержку C++17 и сменили владельца (Embarcadero -> Idera).

    В любом случае, для гуи я бы выбрал именно дэльфи - много сахара, удобный, легко читается, а при необходимости уже писать дллки на плюсах в msvc.
     
  11. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    а зачем такие изыски для окошек? да, и многим ли нужны лямбды? куча публики ваще окошки на джавах клепают иль совсем веб интерфейс :) хотя с другой стороны, конечно, билдер имеет массу замен, тч сугубо окошек ради публика к нему тянуться не будет.
     
  12. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Ну как сказать... Я очень часто использую, а кто-то предпочитает классические каллбэки. Да даже не важно: назвался плюсами - полезай в комитет по стандартизации. Иначе это и не плюсы, и не новый язык, а что-то непонятное. Ведь лямбды - лишь частный пример. Отличий от стандарта в борландовском си хватает.
    Да, тоже заметил моду на Electron и подобные js-движки. Но мне они не нравятся - неторопливые, тяжеловесные.

    Из прямой альтернативы билдеру, скорее, Qt, но IDE там тоже удовольствие так себе, на троечку, хотя сам Qt, как фреймворк, хорош.
    Но в плане визуального дизайнинга дэльфи конкурентов нет. Очень удобно рисовать формы мышкой, мышкой же делать анимации, кидать шейдеры, создавать свои векторные контролы. Влюбился в FireMonkey сразу, как увидел, на что он способен! Пробовал потом и QtWidgets, и даже QML - ну не то, неудобно дизайнить, и всё тут! (И я уже не говорю о необходимости статически билдить Qt, чтобы собрать приложение без зависимостей).

    Вообще, каждый фреймворк хорош по-своему. Даже джавовский FXML. Но лично для себя я выбрал дэльфи и иногда Qt для фронта, а плюсы (в VS на msvc) для бэка.
     
  13. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    и тебе удобно лямбды отлаживать?
    а студия мокрых тоже уступает на твой взгляд?
     
  14. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Хм? А что сложного в их отладке? Я и не знал, что с ними могут быть какие-то сложности...
    Сложно сказать... В студии нет дизайнера для плюсового кода, но если ты про VS Blend и дизайнер для шарпа - судить не берусь, потому что смотрел его лишь поверхностно (на шарпе не пишу) и не знаю, например, как там делать кастомные контролы со своими анимациями и эффектами, чтобы сравнить с дэльфи, но уверен, что всё это там есть.

    Всё-таки, студия - эталон (для меня) для разработки именно на плюсах, а что происходит в её шарповой части - не знаю.
     
  15. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    вроде не так давно они перевели и дельфи и ихний плюсовый компилятор на один и тот же общий бекенд, который эмитит ллвм, не?

    QML очень удобная штука, хотя проседает по скорости (JS-код) в сравнении с чистыми плюсами, но как язык для гуя он очень хороший...

    зависит от компилера, часто на месте лямбды генерируется класс, который инкапсулирует все переменные, которые использованы лямбдой извне, не всегда бывает, что эта конструкция распознается отладчиком (насчет студии не знаю, но гдб бывает путается в показаниях подобных вещей), хоть и должна быть в теории... физически ты видишь функцию с this-указателем и все, остальное адресуется через указатель... если включены оптимизации, то некоторые части этой конструкции могут быть заинлайнены, там бывает знатный бардак по коду...
     
    UbIvItS нравится это.
  16. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    с колбэком разные сложности могут возникать (как и с любой другой функой) и логировать/ладить его работу удобней при классическом подходе.
     
  17. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Не знаю, я года полтора назад последний раз игрался с билдером - там LLVM только ввели и он был на выбор. И, насколько помню, поддерживался только для x64. И отваливались подсказки! Не знаю, как сейчас.
    А про то, что и дэльфи теперь на LLVM, впервые слышу. Интересно было бы сравнить производительность и качество кода.

    QML тоже только по верхам посмотрел. Посмотрел, и вернулся в более привычные QtWidgets, хотя нет-нет, а подмывает разобраться в QML и что-нибудь на нём написать.

    Ни разу не сталкивался с какими-то сложностями при дебаге лямбд в визуалке. Всегда дебажил их, как обычный код, и не задумывался, что где-то с ними могут быть трудности. Но всё это без оптимизаций в Debug-режиме, конечно. А если включать релиз, то проблемы с дебагом начинаются со ВСЕМ, а не только с лямбдами, но это и нормально.
     
  18. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    Да какой бы не был, суть то не в этом. Мне лично просто привычней написать if (edit1->text == '') { indyhttp->get... } чем все эти begin end :=
    Привык к Сишному синтаксису, в паскале путаюсь. А так то, чем билдер плох? Я вот юзал шестую версию (98 год!) и норм, ну изредка юникод глючит. А более новые вообще сказка - если надо по быстрому гуи набросать.

    Лямбды в жизни не юзал, так что не скажу.
     
  19. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Да не сказать, что плох. Тормознее, чем дэльфи, криво работает с подсказками для LLVM (в 10.2.х, в 10.3.х, возможно, пофиксили), но IDE, в целом, неплохая. У меня нет каких-то выраженных языковых предпочтений, одинаково легко писать и на дэльфи, и на си, и на джаве с пхп, поэтому для меня нет проблем с перестройкой на другой язык. Если кому-то удобнее именно си, билдер тоже будет неплохим выбором. Звёзд с неба не хватает, но писать можно. Хотя, если уж писать на плюсах, то сразу в Qt.

    Больше интересует другое: у дэльфи и билдера, по опыту, много проблем с антивирусами - почему-то они не любят дэльфовый софт. Кто-то ещё сталкивался? И как решали?
     
  20. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    Я последнее время сталкиваюсь с другим - гуй пишут на С#(frontend) . со всякими маршалингами и прочим . А либы С++ ые (backend) . Тоже имеет место быть между прочим.