Лекция #28. Symbian development [Лектор - ShTiRLiC]
Автор: Арсений Капулкин
Disclaimer: некоторые опечатки поправлены, некоторые реплики передвинуты. полный лог
[21:01] <ShTiRLiC> Итак, что же такое Symbian OS? Это полноценная 32-битная операционная система, многозадачная, с разделением времени процессов
[21:02] <ShTiRLiC> Работает она на смартфонах и некоторых КПК
[21:02] <ShTiRLiC> В основном, Симбиан ставится на смартфоны Nokia, также Ericsson
[21:02] <ShTiRLiC> Симбиан на рынке смартфонов охватывает порядка 60-70% рынка
[21:02] <ShTiRLiC> Для сравнения, WinMobile - 20%
[21:03] <ShTiRLiC> Собственно, я в лекции не буду рассматривать подробно создание UI
[21:03] <ShTiRLiC> Потому что в играх он все равно графический
[21:03] <ShTiRLiC> Немного про SDK
[21:03] <ShTiRLiC> Его можно скачать на сайте http://forum.nokia.com, весит 145 метров
[21:04] <ShTiRLiC> да, у меня Nokia 6630, и именно отталкиваясь от поддерживаемого им Симбиана я буду отталкиваться
[21:04] <ShTiRLiC> У меня стоит Symbian 8.0a, на довольно известных Nokia N-Gage - Symbian 6
[21:04] <ShTiRLiC> Между ними на устройствах Symbian 7.0s
[21:04] <ShTiRLiC> Еще замечу, что связь у меня не очень стабильная, и я могу вылетать
[21:05] <ShTiRLiC> Так, значит про SDK
[21:05] <ShTiRLiC> Он реализован в виде огромной системы классов
[21:05] <ShTiRLiC> Совсем непривычно, да?
[21:05] <ShTiRLiC> В знакомых большинству системах SDK - всего лишь набор функций в C-стиле
[21:05] <ShTiRLiC> Отсюда специфика разработки приложений под Symbian
[21:06] <ShTiRLiC> Начнем с первого типа программ - EXE
[21:06] <ShTiRLiC> Эти программы все консольные, то есть работают в текстовом режиме
[21:06] <ShTiRLiC> На эмуляторе их легко создавать, т.к. там по сути то же самое, что и в программах на C - одна главная функция и операторы вывода в консоль
[21:08] <ShTiRLiC> Примеры будут преимущественно из SDK
[21:08] <ShTiRLiC> Итак, Hello World для консоли
[21:08] <ShTiRLiC> Вас, возможно, удивит его вид, т.к. отличия от DOS найти сложно
[21:09] <ShTiRLiC> Ну и вообще от консоли
[21:09] <ShTiRLiC> http://www.everfall.com/paste/id.php?fedt6qjtyovi
[21:09] <ShTiRLiC> Вот так всё примитивно
[21:09] <ShTiRLiC> Однако, запустить такую программу на телефоне весьма затруднительно
[21:09] <ShTiRLiC> По крайней мере, у меня ничего не вышло =)
[21:10] <ShTiRLiC> Дело в том, что в формате EXE обычно создаются сервисы - не имеющие интерфейса (UI имею в виду), работающие в фоне
[21:10] <ShTiRLiC> В загруженной ОСи, в которой еще ничего не запущено, работает порядка 64 процессов
[21:10] <ShTiRLiC> Почти все эти программы - консольные
[21:10] <ShTiRLiC> Нас они не очень интересуют, т.к. игры там писать довольно сложно =)
[21:11] <ShTiRLiC> Поэтому закроем эту тему и перейдем к более интересному виду приложения - .APP
[21:11] <ShTiRLiC> Аппы - это визуальные приложения
[21:11] <ShTiRLiC> На самом деле, они не являются истинно исполняемыми файлами, т.к. банально не имеют точки входа =)
[21:12] <ShTiRLiC> APP - это DLL
[21:12] <ShTiRLiC> UI фреймворк симбиана вызывает определенные экспортированные функции из этой DLL, получая в ответ необходимые объекты
[21:13] <ShTiRLiC> Повторю, что в симбиане вся работа приложения построена на объектах, никто не даст вам вызвать какие-либо функции напрямую
[21:13] <ShTiRLiC> Минимальная APP-программа (далее - просто программа) состоит из 4-х классов
[21:14] <ShTiRLiC> И вообще, вся система работы симбиан-программы построена по концепции UI-Документ-Вид
[21:14] <ShTiRLiC> Собственно, это три основные класса
[21:14] <ShTiRLiC> Еще один класс - это т.н. ядро (я называю его так)
[21:14] <ShTiRLiC> Ядро создает документ
[21:14] <ShTiRLiC> В ядре должны содержаться 4 функции
[21:15] <ShTiRLiC> (кстати, минимальная программа легко создается визардом нового приложения, так что вам не придется писать эту рутину руками)
[21:15] <ShTiRLiC> Кратенько перечислю, что они делают, без названий
[21:16] <ShTiRLiC> Также ща закину исходник на everfall
[21:16] <ShTiRLiC> http://www.everfall.com/paste/id.php?worqeq998ob6
[21:16] <ShTiRLiC> Пожалуйста, следите за исходником
[21:17] <ShTiRLiC> Метод AppDllUid должен вернуть UID приложения
[21:17] <ShTiRLiC> UID - это уникальный номер, который есть у каждой программы
[21:17] <ShTiRLiC> Собственно, в целях тестирования можно вбить что-нибудь, не входящее в диапазоны системных UID'ов
[21:18] <ShTiRLiC> Но при релизе необходимо бесплатно запросить у Symbian Ltd. уникальный UID (соответственно его названию =))
[21:18] <ShTiRLiC> Дают обычно пачками, сразу 10-20 штук
[21:18] <ShTiRLiC> Просто если в системе будет более одного UID'а, возникнут проблемы
[21:18] <ShTiRLiC> Далее
[21:19] <ShTiRLiC> CreateDocumentL() - этот метод вызывается фреймворком Symbian
[21:19] <ShTiRLiC> Приложение должно создать и вернуть в ответ указатель на документ приложения
[21:19] <ShTiRLiC> Так, вкратце про документы
[21:19] <ShTiRLiC> Документ - объект хранения данных, например, сейвов или действительно документов
[21:20] <ShTiRLiC> В принципе, в наших целях он использоваться не будет
[21:20] <ShTiRLiC> Все данные лучше грузить руками через сервер файловой системы
[21:20] <ShTiRLiC> Еще сразу объясню, что такое CSymbianPrjDocument::NewL()
[21:20] <ShTiRLiC> Ну, как видно из названия, это статический метод создания
[21:21] <ShTiRLiC> Буква L означает, что функция может вызвать исключение (например, если нет памяти)
[21:21] <ShTiRLiC> Но исключения тут называются "ливами" (Leave)
[21:21] <ShTiRLiC> Просто стандартные эксепшны С++ оказались очень прожорливыми до памяти, и был придуман другой, экономичный механизм
[21:21] <ShTiRLiC> Хотя и более кривой =)
[21:22] <ShTiRLiC> Но об этом попозже
[21:22] <ShTiRLiC> В качестве параметра передается указатель на объект приложения
[21:22] <ShTiRLiC> Стоит отметить, что в предыдущих двух методах мы работали с классом CSymbianPrjApp
[21:23] <ShTiRLiC> Однако его еще надо создать
[21:23] <ShTiRLiC> Функция NewApplication(), которая, как видно из префикса, является экспортируемой, вызывается фреймворком
[21:23] <ShTiRLiC> В ответ приложение создает класс ядра (т.н. мной) и отдает фреймворку
[21:24] <ShTiRLiC> В принципе, функция NewApplication() является единственной явно экспортируемой из нашей DLL (APP)
[21:24] <ShTiRLiC> Дальше объекты создаются по цепочке
[21:24] <ShTiRLiC> Так, ну и последняя функция E32Dll()
[21:25] <ShTiRLiC> Она должна вернуть код ошибки, всегда возвращает KErrNone
[21:25] <ShTiRLiC> Хм, ну она тоже экспортируемая =)
[21:25] <ShTiRLiC> Итак, у нас создан документ
[21:25] <ShTiRLiC> Ща закину исходник класса документа
[21:26] <ShTiRLiC> Кстати, .h закидывать надо для понимания, от чего унаследованы эти мои классы?
[21:26] <ShTiRLiC> Хм
[21:27] <ShTiRLiC> Ну ладно, потом
[21:27] <ShTiRLiC> http://www.everfall.com/paste/id.php?zh0qslssrncl
[21:27] <ShTiRLiC> Тут расписан класс документа
[21:27] <ShTiRLiC> Он практически пуст, за исключением двухстадийного конструктора
[21:27] <ShTiRLiC> Поступила просьба выложить хедеры
[21:27] <ShTiRLiC> Ща объясню про конструктор и выложу
[21:28] <ShTiRLiC> Итак, в симбиане многое сделано не по-человечески
[21:28] <ShTiRLiC> В силу ограниченной оперативной памяти (у меня, к примеру, 10 Мб всего, из них 2 заняты системой)
[21:28] <ShTiRLiC> Хотя может там и больше RAM
[21:29] <ShTiRLiC> Неважно
[21:29] <ShTiRLiC> Стек на каждый поток - всего 8 Кб
[21:29] <ShTiRLiC> Так что на локальных переменных стоит экономить
[21:29] <ShTiRLiC> По этим причинам создание любого объекта происходит в две стадии
[21:30] <ShTiRLiC> Товарищи замечают, что в j2me 300 Кбайт за счастье
[21:30] <ShTiRLiC> Объясняю, что в симбиане весь код нативный, да и объектов зачастую побольше
[21:30] <ShTiRLiC> Но в общем-то запустить 2-3 массивных проги вполне реально
[21:31] <ShTiRLiC> Ну что ж, я все-таки попробую объяснить про двухстадийные конструкторы =)
[21:31] <ShTiRLiC> Для создания объектов в Симбиане не принято использовать new, т.к. все объекты должны наследовать от CBase и иметь дефолтный конструктор приватным
[21:32] <ShTiRLiC> Для создания используется фабрика NewL (или NewLC, разницу поясню позже)
[21:32] <ShTiRLiC> Смотрим в код, читаем мое пояснение
[21:32] <ShTiRLiC> У нас мало памяти, и её всегда может не хватить для создания нового объекта
[21:32] <ShTiRLiC> Это неминуемо вызовет Leave (далее лив), т.е. исключение
[21:33] <ShTiRLiC> Для перехвата ливов можно ставить трапы (аналог catch) или ловушки
[21:33] <ShTiRLiC> Но я с этим не работал, честно говоря
[21:33] <ShTiRLiC> Итак, на первой стадии двухфазного конструктора мы создаем объект простым new
[21:34] <ShTiRLiC> Поступил вопрос, что же я там такое создам в 8 метрах
[21:34] <ShTiRLiC> Что ж, мы рассматриваем исключительно игры, так что игровые объекты могут быть больших размеров
[21:35] <ShTiRLiC> То есть, я может быть захочу создать большой массив, инициализированный нулями
[21:35] <ShTiRLiC> Или создам класс-контейнер с заранее выделенной памятью
[21:35] <ShTiRLiC> Статический массив, грубо говоря
25 июня 2006
Комментарии [2]