OberonCore https://forum.oberoncore.ru/ |
|
Создание исполняемых файлов. https://forum.oberoncore.ru/viewtopic.php?f=81&t=526 |
Страница 1 из 4 |
Автор: | kreol [ Воскресенье, 24 Июнь, 2007 05:09 ] |
Заголовок сообщения: | Создание исполняемых файлов. |
Доброе время суток! Вопрос, наверно, очень простой, но внятного ответа на него я почему-то не нашёл: как в ББ создать исполняемый файл для винды? Я понимаю, что ББ в первую очередь направлен на работу внутри системы, но всё таки хотелось бы научиться создавать независимые от среды приложения, так, как это делает, например, Делфи. В документации к ББ видел такой пример: DevLinker.LinkExe Simple.exe := Simple 1 applogo.Ico ~ Но в самом модуле Simple пока много мне не понятного (собственно неумение создавать ехе-файлы тормозит дальнейшее изучение КП). Не могли бы вы показать простейший пример создания исполняемого файла с пользовательским интерфейсом? Например, в подсистеме Obx есть модуль PhoneUI, реализующий поиск имени по номеру телефона и наоборот в базе данных. Вот как из этого примера сделать приложение для Windows? |
Автор: | Иван Горячев [ Воскресенье, 24 Июнь, 2007 05:30 ] |
Заголовок сообщения: | |
Хотя Вики официально ещё не работает, всё же дам ссылку: http://wiki.oberoncore.ru/index.php/FAQ. Статья ещё не дописана, но общие принципы в ней изложены |
Автор: | Ярослав Романченко [ Воскресенье, 24 Июнь, 2007 13:52 ] |
Заголовок сообщения: | |
Ivor писал(а): Хотя Вики официально ещё не работает, всё же дам ссылку: http://wiki.oberoncore.ru/index.php/FAQ. Статья ещё не дописана, но общие принципы в ней изложены
А где брать WinConsole? |
Автор: | Иван Горячев [ Воскресенье, 24 Июнь, 2007 14:10 ] |
Заголовок сообщения: | |
Ярослав Романченко писал(а): А где брать WinConsole?
У меня в папке /Win/Mod/ Держите: Код: (*
И.Н.Горячев 20.06.2006 Модуль для вывода сообщений на консоль/в файл замечания: На консоль выводит в юникоде, в файл - в кодировке oem Реализует Log.Hook и Dialog.ShowHook *) MODULE WinConsole; IMPORT SYSTEM, WinApi, Log, Dialog, Strings; CONST crlf = 0AX + 0X; TYPE LogHook = POINTER TO RECORD (Log.Hook) END; ShowHook = POINTER TO RECORD (Dialog.ShowHook) END; VAR log : LogHook; show : ShowHook; out : WinApi.HANDLE; write : PROCEDURE (IN s : ARRAY OF CHAR); PROCEDURE WriteConsole (IN s : ARRAY OF CHAR); VAR res, written : INTEGER; BEGIN res := WinApi.WriteConsoleW (out, SYSTEM.ADR(s[0]), LEN(s$), written, 0) END WriteConsole; PROCEDURE WriteFile (IN s : ARRAY OF CHAR); VAR ss : ARRAY [untagged] 256 OF SHORTCHAR; res, written : INTEGER; BEGIN res := WinApi.WideCharToMultiByte(WinApi.CP_OEMCP, {}, s, -1, ss, 255, NIL, NIL); res := WinApi.WriteFile (out, SYSTEM.ADR(ss), LEN(ss$), written, NIL) END WriteFile; PROCEDURE WriteNull (IN s : ARRAY OF CHAR); BEGIN END WriteNull; PROCEDURE WriteParam (IN s, p0, p1, p2 : ARRAY OF CHAR); VAR msg: ARRAY 256 OF CHAR; i: INTEGER; ch: CHAR; BEGIN Dialog.MapParamString(s, p0, p1, p2, msg); i := 0; ch := msg[0]; WHILE ch # 0X DO IF ch = 0DX THEN log.Ln (* TextModels.line *) ELSIF ch = 0EX THEN log.Ln (* TextModels.para *) ELSIF ch = 09X THEN log.Tab (* TextModels.tab *) ELSIF ch >= " " THEN log.Char(ch) END; INC(i); ch := msg[i]; END; log.Ln END WriteParam; (* Log.Hook *) PROCEDURE (log: LogHook) Guard (o: ANYPTR): BOOLEAN; BEGIN RETURN o # NIL END Guard; PROCEDURE (log: LogHook) ClearBuf; BEGIN (* no buffer *) END ClearBuf; PROCEDURE (log: LogHook) FlushBuf; BEGIN (* no buffer *) END FlushBuf; PROCEDURE (log: LogHook) Beep; BEGIN Dialog.Beep END Beep; PROCEDURE (log: LogHook) Char (ch: CHAR); VAR s : ARRAY 2 OF CHAR; BEGIN s[0] := ch; s[1] := 0X; write(s) END Char; PROCEDURE (log: LogHook) Int (n: INTEGER); VAR s : ARRAY 32 OF CHAR; BEGIN Strings.IntToString(n, s); write(s) END Int; PROCEDURE (log: LogHook) Real (x: REAL); VAR s : ARRAY 32 OF CHAR; BEGIN Strings.RealToStringForm(x, 16, 0, 0, " ", s); write(s) END Real; PROCEDURE (log: LogHook) String (IN str: ARRAY OF CHAR); BEGIN write(str) END String; PROCEDURE (log: LogHook) Bool (x: BOOLEAN); BEGIN IF x THEN write("$TRUE") ELSE write("$FALSE") END END Bool; PROCEDURE (log: LogHook) Set (x: SET); VAR i : INTEGER; BEGIN write("{"); i := MIN(SET); WHILE x # {} DO IF i IN x THEN log.Int(i); EXCL(x, i); IF (i + 2 <= MAX(SET)) & (i+1 IN x) & (i+2 IN x) THEN write(".."); x := x - {i+1, i+2}; INC(i, 3); WHILE (i <= MAX(SET)) & (i IN x) DO EXCL(x, i); INC(i) END; log.Int(i-1) END; IF x # {} THEN write(", ") END END; INC(i) END; write("}") END Set; PROCEDURE (log: LogHook) IntForm (x: INTEGER; base, minWidth: INTEGER; fillCh: CHAR; showBase: BOOLEAN); VAR s : ARRAY 32 OF CHAR; BEGIN Strings.IntToStringForm(x, base, minWidth, fillCh, showBase, s); write(s) END IntForm; PROCEDURE (log: LogHook) RealForm (x: REAL; precision, minW, expW: INTEGER; fillCh: CHAR); VAR s : ARRAY 32 OF CHAR; BEGIN Strings.RealToStringForm(x, precision, minW, expW, fillCh, s); write(s) END RealForm; PROCEDURE (log: LogHook) Tab; BEGIN log.Char(09X) END Tab; PROCEDURE (log: LogHook) Ln; BEGIN log.String(crlf) END Ln; PROCEDURE (log: LogHook) Para; BEGIN log.String(crlf) END Para; PROCEDURE (log: LogHook) View (v: ANYPTR); BEGIN (* not supported *) END View; PROCEDURE (log: LogHook) ViewForm (v: ANYPTR; w, h: INTEGER); BEGIN (* not supported *) END ViewForm; PROCEDURE (log: LogHook) ParamMsg (IN s, p0, p1, p2: ARRAY OF CHAR); BEGIN WriteParam (s, p0, p1, p2) END ParamMsg; (* Dialog.ShowHook *) PROCEDURE (h: ShowHook) ShowParamMsg (IN str, p0, p1, p2: ARRAY OF CHAR); BEGIN WriteParam (str, p0, p1, p2) END ShowParamMsg; PROCEDURE (h: ShowHook) ShowParamStatus (IN str, p0, p1, p2: ARRAY OF CHAR); BEGIN write("Status: "); WriteParam (str, p0, p1, p2) END ShowParamStatus; PROCEDURE Install*; BEGIN Log.SetHook(log); Dialog.SetShowHook(show); END Install; PROCEDURE Init; VAR ft : INTEGER; BEGIN NEW(log); NEW(show); out := WinApi.GetStdHandle(WinApi.STD_OUTPUT_HANDLE); ft := WinApi.GetFileType(out); CASE ft OF WinApi.FILE_TYPE_CHAR : write := WriteConsole | WinApi.FILE_TYPE_DISK, WinApi.FILE_TYPE_PIPE : write := WriteFile ELSE write := WriteNull END END Init; PROCEDURE Done; BEGIN Dialog.SetShowHook(NIL); Log.SetHook(NIL); END Done; BEGIN Init; Install CLOSE Done END WinConsole. |
Автор: | Илья Ермаков [ Воскресенье, 24 Июнь, 2007 15:12 ] |
Заголовок сообщения: | |
Вот, уже обсуждалось: viewtopic.php?t=196 viewtopic.php?t=142 |
Автор: | Борис Рюмшин [ Воскресенье, 24 Июнь, 2007 15:19 ] |
Заголовок сообщения: | |
WinConsole модуль не распространённый, поэтому нужно изменения в FAQ внести, что бы работало на базовом ББ. |
Автор: | Иван Горячев [ Воскресенье, 24 Июнь, 2007 15:48 ] |
Заголовок сообщения: | |
Борис Рюмшин писал(а): WinConsole модуль не распространённый, поэтому нужно изменения в FAQ внести, что бы работало на базовом ББ.
С одной стороны да, нехорошо получается С другой стороны, пример должен быть простым. Работа с файлами? В Блэкбоксе это не очень просто. Надо думать... |
Автор: | kreol [ Понедельник, 25 Июнь, 2007 00:23 ] |
Заголовок сообщения: | |
Спасибо за наводки, читаю, разбираюсь. Пример с консолью работает, хотя пока ещё не понял, как осуществлять ввод/вывод (предполагаю, что через Log, как в примере TestExe, но пока ещё не пробовал). С примером оконного приложения сложнее. Как я понял, все возможности создать отдельный ехе-шник сводятся либо к сокрытию главного окна, либо к выделению и перекомпиляции всего фреймворка. И то, и другое "раздувает" приложение до как минимум 1.6 мегабайт (из 5-ого примера Ильи Ермакова на viewtopic.php?t=196 ). Отдельно хотел бы спросить про kernel. Как я понял, на нём держится сам Блекбокс, но что именно он делает, и можно ли как-либо обойтись без него? Даже консольное приложение из примера держится на kernel, а для того же калькулятора в нём многовато лишнего. На самом деле голова кругом идёт от всего этого, поэтому поправьте, пожалуйста, если что-то недопонял =) |
Автор: | Иван Горячев [ Понедельник, 25 Июнь, 2007 00:48 ] |
Заголовок сообщения: | |
kreol писал(а): Отдельно хотел бы спросить про kernel
Основное назначение Kernel - работа с памятью и обслуживание языка Компонентный Паскаль. В частности, именно этот модуль обеспечивает функционирование процедуры NEW(). Так что ежели Вы в программе создаёте экземпляры объектов при помощи NEW() - никуда от Kernelа Вам не уйти. |
Автор: | kreol [ Понедельник, 25 Июнь, 2007 02:16 ] |
Заголовок сообщения: | |
Ivor писал(а): Основное назначение Kernel - работа с памятью и обслуживание языка Компонентный Паскаль. В частности, именно этот модуль обеспечивает функционирование процедуры NEW(). Так что ежели Вы в программе создаёте экземпляры объектов при помощи NEW() - никуда от Kernelа Вам не уйти.
Ну если Компонентный Паскаль не слишком далеко ушёл от обычного, то NEW() выделяет память под динамические переменные, то есть нужен для работы с деревьями, списками и т.п - я правильно понимаю?. Другими словами, для создания того же калькулятора он не нужен? |
Автор: | Иван Горячев [ Понедельник, 25 Июнь, 2007 05:45 ] |
Заголовок сообщения: | |
kreol писал(а): Ну если Компонентный Паскаль не слишком далеко ушёл от обычного, то NEW() выделяет память под динамические переменные, то есть нужен для работы с деревьями, списками и т.п - я правильно понимаю?. Другими словами, для создания того же калькулятора он не нужен?
В принципе да. Только не нужно забывать про другие модули. Практически любой модуль из каркаса потянет за собой Kernel. Уж при реализации графического интерфейса - точно. Другой путь - пользование чистого WinApi, но зачем тогда БлэкБокс? Мне, если честно, не совсем понятно стремление создавать отдельные exe-файлы. Зачем? Заказчику можно отдавать специально сконфигурированную систему, ну только blackbox.exe переименовать во что-нибудь подходящее. А для себя любимого делать отдельные exeшники - вообще нонсенс. |
Автор: | Илья Ермаков [ Понедельник, 25 Июнь, 2007 12:15 ] |
Заголовок сообщения: | |
Рудимент... Психологическое ощущение, что "много файлов - значит недоделано, недозаклёпано наглухо". Смотрите на мир прогрессивней Сколько массивных приложений сегодня написано в стиле отдельных компнент... А мелких с кучей плагинов? Посмотрите на ситуацию так, что плагин - неуклюжая эмуляция модуля... А теперь у вас есть настоящие модули... |
Автор: | kreol [ Понедельник, 25 Июнь, 2007 18:36 ] |
Заголовок сообщения: | |
Илья Ермаков писал(а): Рудимент... Психологическое ощущение, что "много файлов - значит недоделано, недозаклёпано наглухо". Смотрите на мир прогрессивней :-) Сколько массивных приложений сегодня написано в стиле отдельных компнент... А мелких с кучей плагинов? :-) Посмотрите на ситуацию так, что плагин - неуклюжая эмуляция модуля... А теперь у вас есть настоящие модули...
Нет, всё не совсем так. Я понимаю парадигму Оберонов и даже готов с ней согласиться... для себя. Но вот незадача, большинство окружающих меня людей абсолютно незнакомы с идеями БлекБокса и требуют именно исполняемых файлов. Например, необходимо сделать лабораторную работу по программированию. Допустим, написал я её в ББ. Показывать результат в самой среде? Думаю у преподавателей это вызовет некоторое недоумение :) А тащить под каждый проект всю среду, или даже её костяк на полтора мегабайта, когда даже в таком массивном Делфи тот же проект (и с формами, и с кучей прибамбасов) будет весить килобайт 300-400, не резон. Другой пример - маленькие невидимые для пользователя программки, например, отслеживание нажатия каких-либо клавиш. Конечно, это реализуется WinApi-шными функциями, но будем считать, что необходимы ещё какие-то модули, которые есть в ББ. При чём работать программка должна не только у меня, а ещё у кого-то. Согласитесь, что маленький (этак килобайт 30) ехе-файлик, стоящий в автозагрузке, в данном случае удобнее покромсанной среды Чёрного ящика. |
Автор: | Илья Ермаков [ Понедельник, 25 Июнь, 2007 22:14 ] |
Заголовок сообщения: | |
А в этом случае и не нужно кромсать чёрный ящик... Если ГУЙ и библиотеки Блэкбокса не используются, а только сам Компонентный Паскаль и WinApi, то включать придётся только Kernel и ваши модули... Это около 30-40 Кб и получится... |
Автор: | Илья Ермаков [ Понедельник, 25 Июнь, 2007 22:18 ] |
Заголовок сообщения: | |
kreol писал(а): Например, необходимо сделать лабораторную работу по программированию. Допустим, написал я её в ББ. Показывать результат в самой среде? Думаю у преподавателей это вызовет некоторое недоумение
А почему, кстати? Если вам дают выбор на чём писать, то Вы ведь могли бы выбрать и интерпретируемый язык типа Python или Haskell... Где экзешники создать ещё затруднительней, чем в ББ. Можно так и объяснить, что "ББ - это как будто бы среда-интерпретатор, только на самом деле она компилирует..." Да та же Java - их class-файла native-экзешник получить тоже не так легко. Примеров уйма, и преподаватели не могут про них не знать... Вообще, самый реальный способ коротко спозиционировать ББ для незнакомых с ним людей - "платформа, подобная Java, но на Component Pascal". |
Автор: | batyrmastyr [ Понедельник, 25 Июнь, 2007 22:43 ] |
Заголовок сообщения: | |
kreol писал(а): Но вот незадача, большинство окружающих меня людей абсолютно незнакомы с идеями БлекБокса и требуют именно исполняемых файлов. Например, необходимо сделать лабораторную работу по программированию.
Большинству окружающих трудно понять "зачем?" оно надо. Когда нужно было самому показывать прогу проблем не было: можно запросто сделать автооткрытие нужной формы + создать своё меню(рядом с файл, правка и пр.). здесь всё нормально За 2 года только 2 раза были проблемы со сдачей лаб в BlackBox: 1)препод хотел: exe на дискете, с GUI, "дома посмотрю". 2)БД в MS SQL Server. До сих пор не знаю как слепить БД в нем без "помощи" VisualStudio2005 и как заставить это хм.. "добро" работать через ODBC (через который пашет BlackBox). Впрочем при запуске в теминал-классе оно требовало на подключение базы больших прав чем было у препода. 3) как бы проблема - при слове "компонент" один выдал нечто вроде: "я не вижу тут компонентов дельфи! где они?". |
Автор: | kreol [ Понедельник, 25 Июнь, 2007 23:18 ] |
Заголовок сообщения: | |
Илья Ермаков писал(а): ...Да та же Java - их class-файла native-экзешник получить тоже не так легко. Примеров уйма, и преподаватели не могут про них не знать... К сожалению могут. Знания отдельных преподавателей ограничиваются школьным Паскалем и, может быть, Си. К счастью таких немного, поэтому другой пример: есть модуль для ББ, решающий конкретную задачу. Необходимо в срочном порядке (в течение вечера, по интернету) передать этот модуль другому человеку, не знакомому с ББ, для похожих расчётов. Придётся либо объяснять ему хотя бы основы работы в среде (это после того, как он её ещё скачает), либо просто создать екзешник и прислать готовую программу. То есть для себя то можно и в среде всё делать, но как только нужно выпускать программу во внешний мир, тут же возникают проблемы. Илья Ермаков писал(а): А в этом случае и не нужно кромсать чёрный ящик... Если ГУЙ и библиотеки Блэкбокса не используются, а только сам Компонентный Паскаль и WinApi, то включать придётся только Kernel и ваши модули... Это около 30-40 Кб и получится...
Вот это я и хотел услышать =) Всё таки хотелось бы иметь более конкретное представление о том, что же делает Kernel, а точнее какие возможности даёт ядро (а какие добавляются в других модулях). Есть ли какая-нибудь документация по этой теме, или всё познаётся в процессе изучения? |
Автор: | Илья Ермаков [ Понедельник, 25 Июнь, 2007 23:50 ] |
Заголовок сообщения: | |
Kernel - это то, что называют рантаймом, или "поддержкой времени выполнения" для языка программирования. И такая поддержка есть у любого современного языка. Не все конструкции языка транслируются прямо в машинный код, часто используется обращение к такой стандартной библиотеке. В частности, в Компонентном Паскале оператор NEW создает динамический объект - на самом деле происходит обращение к процедуре Kernel.NewRec. Неиспользуемые объекты подбирает сборщик мусора, он тоже содержится в ядре. Вы видите окошки трепов - среда должна уметь обрабатывать сбои в коде модулей. Это тоже делает ядро, правда, само окошко дампа показывают верхние отладочные модули (DevDebug, или, если Dev не включен в поставку приложения, то упрощенный StdDebug). Далее, мы наслаждаемся динамической загрузкой модулей и другими гибкими средствами, которые объединены под названием "метапрограммирование" (когда можно докопаться до переменной по её символьному имени и т.п.) - для этого тоже нужна соответствующая поддержка. И ее тоже дает ядро - поглядите его интерфейс хоть поверхностно, это любопытно: вы увидите структуры Module, Type и т.д. (А если захотите копнуть поглубже, то я писал документацию на ядро, она есть в пакете Active BlackBox в дистрибутивах.) Модуль StdLoader нужен для загрузки модулей в память из файлов. Если всё слинковано статически, то его можно и не включать. Далее, если используете какие-то негуёвые библиотеки типа Strings, Math и т.п. то их можно включать напрямую, не таща за собой весь Framework. Files, Stores - для выгрузки/загрузки данных - это тоже напрямую. А такие вещи, как Text, Form и т.п. - всё это уже тащит в той или иной степени приличную часть Framework'а. Про порядок загрузки среды можете прочитать в документации, в главе "Платформенно-зависимые особенности". |
Автор: | Александр Ильин [ Вторник, 26 Июнь, 2007 09:13 ] |
Заголовок сообщения: | |
kreol писал(а): Илья Ермаков писал(а): Если ГУЙ и библиотеки Блэкбокса не используются, а только сам Компонентный Паскаль и WinApi, то включать придётся только Kernel и ваши модули... Это около 30-40 Кб и получится... Вот это я и хотел услышать =)Тогда, возможно, вы также захотите услышать, что без использования Kernel на чистом WinApi exe-шник будет от 3.5Кб. : ) Код: MODULE PrivEmpty; END PrivEmpty. ^Q DevLinker.LinkExe Empty.exe := PrivEmpty ~ kreol писал(а): Всё таки хотелось бы иметь более конкретное представление о том, что же делает Kernel, а точнее какие возможности даёт ядро (а какие добавляются в других модулях).
Илья меня опередил. Нажимаю "Предв. просмотр", а там уже более полный ответ : )) |
Автор: | Ярослав Романченко [ Вторник, 26 Июнь, 2007 10:00 ] |
Заголовок сообщения: | |
А скрыть главное окно BB можно? Что-бы было видно только одно моё окно. т.е. реализовать SDI приложение а не MDI... |
Страница 1 из 4 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |