OberonCore
https://forum.oberoncore.ru/

StdIn/StdOut в BlackBox
https://forum.oberoncore.ru/viewtopic.php?f=81&t=1929
Страница 1 из 2

Автор:  Роман М. [ Понедельник, 05 Октябрь, 2009 20:48 ]
Заголовок сообщения:  StdIn/StdOut в BlackBox

Приветствую всех посетителей и завсегдатаев форума!
Я являюсь новичком в Компонентном Паскале и, в частности, в BlackBox. На данный момент, для меня, BlackBox оправдывает своё название, ибо он для меня - чёрный ящик. Случайно забрёл на этот ресурс, ища информацию по Оберону и меня заинтересовали новые возможности по сравнению с Паскалем. Сам я начал изучение программирования с Бейсика, в школе, затем на Турбо Паскале и по сей день программирую, как хобби, используя, преимущественно, Free Pascal и Delphi. Языки программирования сильно эволюционировали за это время, но осталась привязка к консоли.
Фактически, до знакомства с BB, я даже не мог себе представить, что язык программирования может быть отвлечён от этой привязки, и, при этом, оставаться способным интерактировать с пользователем. Особенно тяжело это понять после UNIX-подобных систем, где консоль является частью ядра.

Итак, это было вступление. А теперь, к делу.
Прошерстив различную документацию по КП, я решил начать с простой программы. Как некоторые уже догадались, то была программа "Привет, Мир!". Само собой, вывод на экран в ТП производится процедурами write/writeln. Как быть? Лезем в документацию и находим, что ... собственно, нет прямого аналога текстового экрана консоли и привычных StdIn/StdOut.
В одной из подсистем я нахожу в документации, что вывод осуществляется через модуль Out - некий аналог консоли. Но это же не полноценное решение и, к тому же,
Цитата:
This module is provided for compatibility with the book "Programming in Oberon" by Reiser/Wirth. It is useful when learning the language. It is not recommended for use in production programs.
:(

Как же быть? Каким образом я смогу переписать программы, написанные для Turbo/Free Pascal в Component Pascal? Если я упустил, простите меня, я исправлюсь. :)

Автор:  Илья Ермаков [ Понедельник, 05 Октябрь, 2009 21:03 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Уважаемый Роман!

В принципе, материалов, по которым можно постепенно изучать среду, сейчас достаточно; правда, они не собраны прямо в одном месте.

Попробуйте начать отсюда:
http://317.metasystems.ru/,
http://317.metasystems.ru/doku.php/blackbox

Автор:  Евгений Темиргалеев [ Понедельник, 05 Октябрь, 2009 21:09 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Модули In и Log (StdLog). Консоль для вывода - окно Log (Журнал), консоль для ввода - любой текстовый документ (сначала Вы туда вводите, а потом "запускаете" "программу", которая зачитывает введённые данные).

В ББ см. F1->Overview by Example (Демонстрация на примерах). ObxHello0 - "Здравствуй мир". ObxFern - исп-ся In.

Более подробные примеры и более удобную версию модуля In найдете в школьном пакете: http://www.inr.ac.ru/~info21/software.htm

Может чего полезное в вики найдете, если не смотрели ещё: http://oberoncore.ru/wiki/ ... но там пока не густо...

Автор:  Info21 [ Понедельник, 05 Октябрь, 2009 21:27 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Роман М. писал(а):
Прошерстив различную документацию по КП, я решил начать с простой программы. Как некоторые уже догадались, то была программа "Привет, Мир!". ...
Посмотрите на сайте http://www.inr.ac.ru/~info21/, там на первой странице ссылки Как начать работу... и ниже все инструкции собраны в pdf.

Если бы Вы сразу начали оттуда, то вопросов бы не было.

Автор:  Роман М. [ Среда, 07 Октябрь, 2009 01:11 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Всё хорошо, но это далеко от возможностей привычного writeln, включающего форматированный вывод на терминал.
И как быть, если мне нужно получить интерактивную среду, в которой в ответ на действия пользователя я могу решить что выводить на экран? Допустим, я захотел написать программу, подобную клиенту ssh. Что тогда?
Выходит, что нет модулей для работы с терминалами...
Да, терминалы уже устарели, но всё же это не причина игнорировать их существование сегодня.

Автор:  Роман М. [ Среда, 07 Октябрь, 2009 01:36 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

В добавок, мне хотелось бы ознакомиться подробнее со средствами ввода/вывода информации.
Я так понимаю, реализация БлэкБокса подразумевает, что я буду использовать GUI-средства для ввода информации или же через модуль In.

Не могли бы вы направить меня на конкретные источники для чтения, а то тяжело такую гору информации читать, да и жаль потерянного времени.

Автор:  А.П. [ Среда, 07 Октябрь, 2009 06:48 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Роман М. писал(а):
...хотелось бы ознакомиться подробнее со средствами ввода/вывода информации.

Средств модулей In и StdLog вполне достаточно для любого оформления ввода/вывода в учебных задачах, в том числе форматного "а-ля writeln". Прочитайте инструкции к этим модулям.
В "настоящих" программах ввод/вывод осуществляется из/в файлы либо через диалоговые формы в интерактиве с пользователем. Диалоговые формы в ББ строить несложно, в простых случаях они получаются автоматически благодаря наличию специальных меток ("*", "-") у имен переменных и процедур. Для обмена значениями используются процедуры модуля Dialog. Если штатных средств ББ всё-таки покажется мало, в Коллекции Зинна есть подсистема Ctls, расширяющая базовые возможности.
Могу выслать в личку подборку моих примеров на эти темы из сборника учебных примеров.

Если под выводом Вы понимаете еще и графику, то это - отдельная большая тема. Опять же, есть несколько уровней - от черепашки и графики "а-ля турбопаскаль" до трехмерной графики.

Автор:  Иван Горячев [ Среда, 07 Октябрь, 2009 07:10 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Роман М. писал(а):
В добавок, мне хотелось бы ознакомиться подробнее со средствами ввода/вывода информации


Есть три пути, как говорится.

1. "Консольный" интерфейс составных документов: в среде ББ открывается документ, в котором пишутся необходимые данные (как текст, так и "вьюшки"). Ввод данных идёт с помощью TextMappers.Scanner. Вывод через TextMappers.Formatter в другой документ. Способ с точки зрения внешнего пользователя весьма экзотический, хотя и мощный (особенно в части вывода результатов). Смотреть подробнее - документация ББ, описание работы с текстами (подсистема Text в частности)
2. "Традиционный" графический - через диалоги. Работает подсистема Forms. Подробнее - опять же в документации.
3. Честный консольный. Вывод идёт через Log (не StdLog!), ввод - отдельный модуль. Для этого нужны модули реализации консольного в/в, коих здесь было минимум два варианта. Тут вообще всё просто - сплошные процедуры

Отмечу только, что подсистему Text всё равно придётся пристально изучать. Хотя бы ради генерации красивых отчётов.

Автор:  Евгений Темиргалеев [ Среда, 07 Октябрь, 2009 08:35 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Роман М. писал(а):
В добавок, мне хотелось бы ознакомиться подробнее со средствами ввода/вывода информации.Я так понимаю, реализация БлэкБокса подразумевает, что я буду использовать GUI-средства для ввода информации или же через модуль In.

Не могли бы вы направить меня на конкретные источники для чтения, а то тяжело такую гору информации читать, да и жаль потерянного времени.
Скачайте школьную сборку
http://www.inr.ac.ru/~blackbox/rsrc/Bla ... um.2008.7z (отсюда http://www.inr.ac.ru/~info21/software.htm). Читайте:
Примеры->Некоторые примеры
Примеры->Создание простых диалогов

Автор:  Иван Денисов [ Пятница, 09 Октябрь, 2009 18:47 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

На сколько я понял, для просто консольных приложений без GUI проще использовать XDS ?

Автор:  Илья Ермаков [ Пятница, 09 Октябрь, 2009 18:49 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Да и в ББ без проблем.
Есть модули консоли. Если никто не напомнит, где оно уже лежит, могу выложить своё.

Автор:  Rifat [ Пятница, 09 Октябрь, 2009 23:20 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Можно и свой модуль написать для создания консольных приложений. Для этого надо знать всего несколько WinApi функций: GetStdHandle, ReadConsole, ReadFile. В принципе этого достаточно, чтобы создать простенькое консольное приложение.
Еще при линковке желательно указать параметр dos:
DevLinker dos myprog.exe := ...
Честно говоря не знаю, что будет если этот параметр не указать, возможно и без него будет собираться и работать консольное приложение.

Автор:  Александр Ильин [ Суббота, 10 Октябрь, 2009 06:11 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

divan писал(а):
На сколько я понял, для просто консольных приложений без GUI проще использовать XDS ?
Да, это так, поскольку разработчики XDS активно использовали консоль для собственных нужд, а ББ совершенно ей не пользовались. В XDS стандартные модули In и Out прекрасно работают с консолью (одна тонкость только есть: Out.String (0AX) выводит два символа: 0DX и 0AX). В стандартном комплекте ББ нет модулей для работы с консолью. Тут на форуме выкладывали модуль для вывода (подставляется в стандартный Log), а для ввода не припомню. Даже если эти модули добавить в ББ, то консольное приложение при трапе будет показывать MessageBox, так как в модуле Kernel иного не предусмотрено.

Автор:  Илья Ермаков [ Суббота, 10 Октябрь, 2009 07:18 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Параметр dos говорит линковщику поместить в PortableExecutable флаг открытия консольного окна при старте.

Иначе нужно руками открывать консоль через AllocConsole.

Автор:  Борис Рюмшин [ Суббота, 10 Октябрь, 2009 10:17 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Хорошо бы, если кому по форуму реализации консолей подвернутся спихнуть бы их в Вики....

Автор:  Иван Горячев [ Суббота, 10 Октябрь, 2009 12:50 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Моё лежит тут. А в вику не пускает :(

Автор:  Александр Ильин [ Суббота, 10 Октябрь, 2009 12:57 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Ещё был бы отличный проектик: создать базовый набор для консольного ББ. Например, в виде подсистемы Con. И компилировать в консоль как при кросс-разработке: вместо Log ставим ConLog, вместо Kernel ставим ConKernel и т.д. В общем, подумать и сделать законченный продуктик.

Автор:  Роман М. [ Воскресенье, 11 Октябрь, 2009 12:56 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Пока не было возможности развивать вопрос, остановился пока на таком доработанном варианте модуля Terminal (от Ильи Ермакова):
Код:
MODULE Terminal_mod;
(**

   Console input / output
   (useful for low-level debugging)
   Contributers: Roman M.
   Author: Ilya Ermakov

**)

   IMPORT WinApi, S := SYSTEM;
   
   CONST
      ln = 0DX + 0AX; (* CR/LF *)
     
   VAR
      in, out: WinApi.HANDLE;
      res, n: INTEGER;
      buf: ARRAY 1024 OF SHORTCHAR;
      cs: WinApi.CRITICAL_SECTION;

   PROCEDURE InitAtomic*;
   BEGIN
      WinApi.InitializeCriticalSection(cs);
   END InitAtomic;

   PROCEDURE BeginAtomic* ;
   BEGIN
      WinApi.EnterCriticalSection(cs)
   END BeginAtomic;
   
   PROCEDURE EndAtomic* ;
   BEGIN
      WinApi.LeaveCriticalSection(cs)
   END EndAtomic;
   
   PROCEDURE AllocConsole;
      VAR res: INTEGER;
   BEGIN
      res := WinApi.AllocConsole();
      res := WinApi.SetConsoleCP(1251)
   END AllocConsole;
   
   PROCEDURE FreeConsole*;
      VAR res: INTEGER;
   BEGIN
      res := WinApi.FreeConsole();
   END FreeConsole;
   
   PROCEDURE OpenStdOut;
   BEGIN
      AllocConsole;
      out := WinApi.CreateFile("CONOUT$", WinApi.GENERIC_READ + WinApi.GENERIC_WRITE, {}, NIL,
         WinApi.OPEN_EXISTING, {}, 0);
      res := WinApi.GetLastError()
   END OpenStdOut;
   
   PROCEDURE OpenStdIn;
   BEGIN
      AllocConsole;
      in := WinApi.CreateFile("CONIN$", WinApi.GENERIC_READ + WinApi.GENERIC_WRITE, {}, NIL,
         WinApi.OPEN_EXISTING, {}, 0)
   END OpenStdIn;
   
   PROCEDURE AssignOutput* (IN file: ARRAY OF CHAR);
      VAR res: INTEGER;
   BEGIN
      IF file # "" THEN
         out := WinApi.CreateFileW(file, WinApi.GENERIC_WRITE, WinApi.FILE_SHARE_READ +
            WinApi.FILE_SHARE_WRITE, NIL, WinApi.CREATE_ALWAYS, {}, 0);
(*         res := WinApi.SetFilePointer(out, 0, NIL, WinApi.FILE_END) *)
      ELSE
         OpenStdOut
      END
   END AssignOutput;

   PROCEDURE String* (IN s: ARRAY OF SHORTCHAR);
   BEGIN
      res := WinApi.WriteFile(out, S.ADR(s), LEN(s$), n, NIL)
   END String;
   
   PROCEDURE Char* (c: SHORTCHAR);
   BEGIN
      res := WinApi.WriteFile(out, S.ADR(c), 1, n, NIL)
   END Char;
   
   PROCEDURE Ln* ;
   BEGIN
      res := WinApi.WriteFile(out, S.ADR(ln), LEN(ln), n, NIL)
   END Ln;
   
   PROCEDURE ReadString* (OUT s: ARRAY OF SHORTCHAR);
   BEGIN
      res := WinApi.ReadFile(in, S.ADR(buf), LEN(buf), n, NIL);
      s := buf$
   END ReadString;
   
   PROCEDURE ReadLn* ;
      VAR s: ARRAY 16 OF SHORTCHAR;
   BEGIN
      ReadString(s)
   END ReadLn;

BEGIN
   InitAtomic;
   IF out = 0 THEN
      OpenStdOut
   END;
   OpenStdIn;
END Terminal_mod.


Код:
MODULE Con_test;
(* тестовый модуль *)

IMPORT Term := Terminal_mod;

PROCEDURE Start*;
BEGIN
   Term.BeginAtomic;
   Term.String("Hello!"); Term.Ln;
   Term.EndAtomic;
   Term.FreeConsole
END Start;

END Con_test.

^Q Con_test.Start
Проверял несколько раз, при повторных запусках консоль уже не появляется.
Пока оставил идею в сторону.
Модуль Terminal/Con определённо нужен для "обратной совместимости" с программами на Object Pascal.

Автор:  Info21 [ Воскресенье, 11 Октябрь, 2009 13:35 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Роман М. писал(а):
Модуль Terminal/Con определённо нужен для "обратной совместимости" с программами на Object Pascal.
Не очевидно.

Достаточно, чтобы программа открывала вьюшку, эмулирующую командную строку -- что делается довольно просто (в Obx есть примеры почти готовые).
Совсем не надо весь Блэкбокс уродовать для этой самой совместимости.

Программа пусть будет оформлена как процедура в модуле, а открывание консольного окошка вставить в секцию инициализации модуля.
Вроде, нормальная схема?

---------
Вот, кстати, пример неявного предположения и инерции мышления.
Трудно их (неявные предположения) у себя из головы выковыривать.

Автор:  Роман М. [ Воскресенье, 11 Октябрь, 2009 14:02 ]
Заголовок сообщения:  Re: StdIn/StdOut в BlackBox

Уродовать концепцию компонентного Паскаля не желаю, поэтому и не спорю.
Именно на такую схему я и расчитываю.

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/