Особенности программирования BeOS API Часть 2


Отступление 1 — Инструменты.

    Для аскетичных пришельцев-радикалов из мира юникс, достаточно будет следующих сведений:

    Имеется vim. И ряд других редакторов консольного режима.

    Шаблон makefile для BeOS находится в /boot/develop/etc/.

    Имеются версии gcc — 2.9 и 2.95*. 3-й gcc можно собрать, но применять не получится из-за ABI.

    Функции уровня POSIX находятся в libroot.so (glibc+libm+еще что-то, хотя не полностью).

    Библиотека стандартных классов С++ — libstdc++.r4.so.

    Значительная часть BeOS API, прежде всего интерфейсная — в libbe.so.

    Для менее радикальных отмечу, что можно использовать GUI-редакторы Pe (http://bebits.com/app/3356), Eddie (http://bebits.com/app/95) и BeIDE — /boot/develop/BeIDE/BeIDE.

    Последнее — это стандартная для BeOS интегрированная среда разработки (от Metrowerks), проект-ориентированная, но позволяет, для пуристов, генерировать и make-файлы из проекта.

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

    Инструменты Быстрой Разработки Приложений (RAD) — BeXL, MeTOS, VisualBe, BeBuilder — на этом этапе категорически не рекомендуются.

    Может быть рекомендована добавка к BeIDE — Don’tWorry(http://bebits.com/app/2374) — помогает в изучении иерархии классов.

    Тем, кто привык к IDE, освоить BeIDE будет легко, впрочем, несколько замечаний необходимы:

    1)Файлы BeOS-проектов имеют расширение *.proj. Для создания своего проекта, создайте сначала новую папочку и скопируйте туда файл(ы) из /boot/develop/BeIDE/stationery/x86/BeApp/ — это шаблон стандартного BeOS-проекта. Их можно переименовать под ваш проект. Запустите BeIDE двойным щелчком на proj-файле.

    Впрочем, можно и просто запустить BeIDE, cоздать «новый проект» и выбрать тип шаблона прямо изнутри BeIDE.

    2)А теперь не стоит сразу переходить на «русский народный» по поводу «диких» клавиатурных сочетаний (шорткатов) — они все настраиваются под ваш вкус в окне проекта — Edit->Preferences->General->KeyBindings. Цвета настраиваются в Edit->Preferences->Editor->SyntaxStyling.

    Для тех же, кто не боится «Читать Эти Грёбаные Руководства» (RTFM) — есть мануал BeIDE от Metrowerks

Теперь, когда мы знаем, чем писать программы, можно открыть Главный Секрет «как писать» — каждая программа должна иметь начало. Менее главный секрет — программа в BeOS, как и любая другая С и С++ программа, начинается с выполнения функции main().

Никаких особых подвохов тут нет, единственно, что можно заметить на будущее, если программу запускать из командной строки с аргументами, то эти аргументы могут быть считаны не только традиционным способом в качестве параметров main() — argc и argv, но также и получены BeOS-приложением более натуральным для BeOS способом — через сообщение главному циклу сообщений (Message Loop) BeOS-программы. Такое сообщение отправляется AppServer-ом автоматически, при наличии этих самых аргументов.

Еще стоит отметить, что в GUI-шных BeOS-программах код в самой main обычно крайне минималистичен, и предназначен, главным образом, для запуска BeOS Application (наследник класса BApplication )- по сути того самого главного Message Loop. К сожалению, рассказать, что такое классы и что такое сообщения одновременно — довольно затруднительно, поэтому начну с сообщений.

Отступление 2. Сообщения — отправители, диспетчеры, обработчики, прерывания.

    В первой части введения мы уже задавались вопросом — как это все программы умудряются работать одновременно? — и частично на него ответили. Необъясненным осталось то, как же всё-таки все эти куски, которые считают, что каждый из них — чуть ли не единственный на белом свете, взаимодействуют с друг другом в многозадачной операционной системе.

    Ответ простой — они обмениваются телеграммами/письмами/SMS-ками/бандеролями/и даже грузовыми контейнерами:) — т.е. сообщениями (в unix-мире больше распространена концепция сигналов — signals, в BeOS signals реализованы в слое эмуляции POSIX).

    Щелкнул мышкой — драйвер сработал, послал сообщение InputServer-у, тот — ApplicationServer-у, AppServer — в свою очередь — программе.

    Хочет программа что либо нарисовать — сообщение AppServer-у, а уж доля того — общаться с драйверами видеокарты.

    Соответственно, у всех жильцов в общежитии операционной системы должны быть способности к

    1)отправке сообщений — отправитель в BeOS «называется» BMessenger,

    2)приему-перехвату сообщений и решению, что с ними дальше делать (диспетчеризация) — этим занимается цикл приема и распределения сообщений — message loop, BLooper в BeOS,

    3)обработке сообщений (обработчик по английски — handler) — BHandler в BeOS.

    (Как вы могли догадаться, названия компонент-классов BeAPI начинаются с ‘B’.)

    Теперь немножко о самих BeOS-сообщениях, для тех знатоков, кто сталкивался с сообщениями в других ОС/платформах. Их отличительное качество — практически «свободный» формат. Единственный обязательный член BMessage — признак «ЧТО» (what). Например, если в сообщении, полученном BeOS-приложением этот what==B_ARGV_RECEIVED (константа, определенная в системе) — это означает, что программа была запущена из командной строки и там имеются аргументы — см. параграф про main().

    А дальше (я не зря упомянул не только телеграммы, но и бандероли, и грузовые контейнеры) — в теле сообщения может содержаться практически все что угодно, любого размера. В теории — хоть DVD-диск упакуй туда. Но не рекомендую:)

    Раз уж мы вдарились в объяснения, как работает многозадачная/многопоточная OS, можно спуститься поближе к земле, то есть к кремнию и железу, и пояснить, на чем все это основано. То есть, рассказать о прерываниях. Знатоки, а также ленивые и нелюбопытные могут смело пропустить нижеследующее безо всякого ущерба.

    Есть два способа реагировать на изменения в обстановке — программный опрос (polling) и прерывания (interrupts).

    Первый — это когда программа состоит из ужасных запутанных циклов, проверяющих по кругу состояния всего и вся — портов устройств, программ, системного таймера (чтобы время от времени переключаться между программами). На вид просто, с этого народ обычно начинает писать программы, на деле, написать ОС, работающую таким способом — надо быть крутым садомазохистом.

    Это как если бы телефонная связь работала по тому принципу, что вам надо было бы раз в секунду подбегать к трубке и слушать, не пытается ли кто с вами пообщаться.

    Второй — прерывания. Когда какому-нибудь устройству или программе невтерпеж пообщаться (например, буфер последовательного порта уже почти забит данными из модема) — они «звонят» процессору — выставляют запрос на прерывание, тот самый печально известный IRQ (interrupt request). Дальше начинается некоторая машинерия — кого обслужить первым и т.д., но, в конечном счете, запоминается текущее состояние системы, выполнение предыдущих программ прекращается (откладывается), и система переходит на выполнение кода, указанного в запросе на прерывание.

    После удовлетворения потребности в тусовке, система возвращается к выполнению отложенных задач.

    Так вот, и разделение времени между программами из первого объяснения про многозадачность, и создание/перехват/обработка сообщений из второго, происходят при помощи прерываний.

    Для первого используются прерывания от системного таймера, для второго — используются так называемые программные прерывания. Аналогию с телефоном/пэйджером/SMS можете додумать сами 🙂

Теперь читатель знает почти достаточно, чтобы показать ему, как выглядит запуск BeOS-программы.
А выглядит он, в сокращенном виде, так:

    --------------------------------
    main()
    {
    KrutajaProgramma.Run()
    -------------------------------
    или так:
    main()
    {
    SuperPuperProgramma->Run()
    --------------------------------

Этот Run() — метод класса BApplication, запускающий главный цикл — приемник/диспетчер/обработчик сообщений для BeOS-программы в целом.

Охх, опять эти грабли, это «знает почти достаточно» — классы, методы, энкапсуляция, наследование, полиморфизм и прочие ругательства…боюсь что начало этого цикла статей так и будет состоять из сплошных отступлений. Может, отложим до завтра?:) Да и караул уже устал.

Разве что сейчас можно упомнять для знатоков, что be_app из предыдущей главки — это глобальный (доступный всем компонентам программы) указатель на объект этой программы. Переменная с таким именем создается автоматически, при создании объекта-наследника BApplication.

(В данном случае be_app == SuperPuperProgramma или be_app == &KrutajaProgramma).
А в связи с отступлением про сообщения, надо упомянуть также то, что BApplication является наследником BLooper и BHandler.


При использовании материалов сайта ссылка обязательна! (Copyright by www.avs-info.ru 2006)