Это вопросы, которые возникли у меня (да и у многих других) во время освоения
Symbian C++ и ответы на них, полученные в результате поисков на форумах или
методом проб и ошибок.
---------------
Q: Можно ли без SDK собрать готовый проект?
----
A: Нет.
---------------
Q: Можно ли скомпилить готовые исходники, не имея IDE?
----
A: Конечно! Вначале надо создать abld.bat и пачку make'ов вызовом bldmake bldfiles
из той папки, где лежит файл *.inf, затем запускать abld build <платформа> udeb/urel.
Подробности - в SDK и в help'е консольных утилит bldmake, makmake, abld и др.
---------------
Q: Программа на JAVA из SDK требует какую-то старую виртуальную машину. У меня более новая - и ничего не запускается...
----
A:
Вариант 1, топорный. Записываем, какая версия нужна. В ветке реестра
HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\
есть раздел с имеющейся версией - создаём точно такой же, но с нужным номером версии. Можно ещё проделать то же самое с остальными разделами ветки HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft. Теперь программа должна запуститься.
Но при этом в ней может ничего не работать. Что ясно доказывает - совместимость
JAVA - это не более, чем маркетинговый ход.
Вариант 2, правильный.
СНОСИМ имеющуюся JAVA-машину, заходим по адресу
http://java.sun.com/products/archive/ и качаем нужную машину. Виртуальные машины, в названии которых есть SDK, содержат библиотеки для разработчиков, и для наших целей не нужны.
---------------
Q: Где документацию брать?
----
A: Программисты под Windows привыкли, что у них есть MSDN, программеры на
JAVA привыкли к тому, что к любой библиотеке приложен javadoc. Здесь хуже -
документация достаточно слабая, примеры обычно представляют собой готовые
проекты, где, кроме собственно примера есть ещё с десяток файлов.
Приходится активно использовать поиск текста в заголовочных файлах в папке
%EPOCROOT%\\Epoc32\\Include и, конечно же, поиск в Web, благо, сайтов с инфой много.
Отправная точка поисков, как правило forum.nokia.com, разделы Discussion
Boards и Symbian/C++ Code and Examples. Кроме того, symbian.com и newlc.com.
Довольно интересно пишет вот этот финский товарищ:
http://www.cs.helsinki.fi/u/mraento/symbian/Русской документации не существует, единственная попавшаяся мне в руки книга
Горнакова С.В. - ниже плинтуса. Из неё становится ясным только одно - автор
может поставить CodeWarrior на компьютер :-) Если есть большие проблемы с
техническим английским - займитесь лучше чем-то другим.
---------------
Q: Как меня задолбали эти длинные пути, эти коммандные строки...
A: В FAR есть пользовательское меню F2 (не путать с жалкой пародией, которая
вылазит по Ctrl+D в Total!). Вот туда нужно добавить соответствующие строки.
Добавляется это в визуальном режиме по кнопке Insert или вставкой команд
в текстовый файл (нажмите Alt+F4 в пользовательском меню)
У меня это оформлено в виде подменю "Команды Symbian". Благодаря использованию
переменной EPOCROOT вместо жёсткого задания путей, это будет работать и в другом
Far'е, однако накладывает ограничение: меню работает, только если текущая папка
фара находится на том же диске, где установлен Symbian SDK.
Чтобы это всё работало в вашем FAR - должен быть установлен стандартный плагин
Far Commands (а он устанавливается по умолчанию вместе с FAR)
s: Команды Symbian
{
F1: SDK Help
%EPOCROOT%\\Series60Doc\\start.chm
f: Синтаксис файлов:
{
s: Синтаксис sis-файла
edit:
m: Синтаксис mmp-файла
edit:
}
-:
s: Создать sis-файл
macro:post ShiftAlt6 "*.pkg" Esc CtrlIns "makesis -v " ShiftIns Enter
g: Сборка стандартного проекта для мобилы (armi)
cd !?Корневая папка проекта?(!\\)!\\install
del /Q *.sis
CD ..\\group
abld build armi urel
CD ..\\install
macro:post ShiftAlt6 "*.pkg" Esc CtrlIns "makesis -v " ShiftIns Enter
a: Создать abld
bldmake bldfiles
m: Мобильная сборка (c выводом лога)
edit:v: Создать проект для VC
!?Папка group?(!\\)!\\abld.bat makefile vc6
-:
p: Папка с проектами
CD %EPOCROOT%\\Epoc32\\BUILD\\
r: Папка с релизами armi
CD %EPOCROOT%\\Epoc32\\Release\\armi\\urel
1: Диски
{
с: Диск С
CD %EPOCROOT%\\Series60\\Epoc32\\Wins\\c
d: Диск D
CD %EPOCROOT%\\Series60\\Epoc32\\Wins\\d
z: Диск Z
CD %EPOCROOT%\\Epoc32\\Release\\wins\\udeb\\z
}
}
---------------
Q: Ошибка компиляции - unresolved external symbol _chkstk (также может быть
__aullshr, __allshl ...). Ошибка происходит при сборке под WINS, сборка для
ARMI или THUMB происходит без ошибок. Что делать?
----
A: В mmp-файле необходимо написать строки:
START WINS
WIN32_LIBRARY msvcrt.lib
END
---------------
Q: Ошибка компиляции при сборке для телефона:
'MyApplication.app' has initialised data.
Под эмулятором - всё хорошо. Что бы это значило?
----
A: Это значит, что тебе пора отвыкать использовать глобальные переменные.
Глобальная переменная в app может быть только одна - UID приложения.
Ищи все глобальные переменные и засовывай их внутрь классов.
---------------
Q: Блин! Но у меня в проекте 110 файлов уже! И с сотню глобальных переменных.
Что, всё это переписывать?
----
A: Ага! Глобальные переменные могут быть только при создании EXE.
---------------
Q: EXE и APP - в чём разница?
----
A: О, во многом. Но, как правило, EXE - это консольное приложение, и оно
запускается с коммандной строки. Так что разница примерно такая же, как
между консольным и оконным приложением в Windows
---------------
Q: Что-то не совсем понял, как тут DLL-ки работают? Где аналог GetProcAddress?
----
A: Тут нет аналога GetProcAddress - всё интереснее. Принцип такой:
1. В приложении объявляется класс с виртуальными функциями.
Например:
class CDllClass
{
CDllClass();
~CDllClass();
virtual bool GetBoolean(){return false;} // virtual
virtual int GetNumber(int start)=0; // pure virtual
};
2. В DLL-ке объявляется класс, отнаследованный от этого класса, виртуальные
функции переопределяются.
Например:
class CDllClass1 : public CDllClass
{
CDllClass(){}
~CDllClass(){}
//-------------------
bool GetBoolean()
{
return true;
}
//-------------------
int GetNumber(int start)
{
return start+1;
}
};
3. DLL должна экспортировать функции только такого типа:
typedef TInt (*TLibraryFunction)();
Т.е. все экспортируемые функции не имеют параметров и возвращают целые числа.
В такой функции создаём экземпляр отнаследованного класса и возвращаем указатель
на него:
TInt DllStart()
{
CDllClass1 * pDllClass = new CDllClass1;
return (TInt)pDllClass;
}
4. В приложении нужно вызвать эту функцию:
RLibrary lib;
lib.Load(_L("c:\\dlls\\mydll.dll"));
TLibraryFunction func = lib.Lookup(1); // Вызываем функцию по смещению 1
CDllClass * pDllClass = lib.func();
int number = pDllClass->GetNumber(100); // number = 101
---------------
Q: Клёво! А я хочу ещё из dll-ки вызвать функцию моего приложения.
----
A: Тут в точности, как в WinAPI.
1. В заголовочном файле, подключаемом и к проекту приложения и к проекту dll,
объявляем указатель на функцию, например:
typedef bool (*SET_INFO)(int hoster, const TDesC &text);
2. В проекте приложения пишем код функции.
bool SetInfo(int hoster, const TDesC &text)
{
CMyWindow * win = (CMyWindow*) hoster;
win->SetTextL(text);
}
3. Указатель на функцию inf передаём в dll-ку (вызовом какой-то из функций
класса). Например:
В dll:
class CDllClass1
{
//....
TInt32 m_funcHandle;
TInt32 m_hoster;
void SetFuncHandle(int hoster,int handle)
{
m_hoster = hoster;
m_funcHandle = handle;
}
//....
void CallAppFunction()
{
m_funcHandle(m_hoster,_L("My title!"));
}
//....
};
В app:
class CDllClass
{
//.....
virtual void SetFuncHandle(int hoster,int handle)=0;
//.....
}
//.....
//.....
CDllClass * pDllClass;
//...
SET_INFO inf = SetInfo;
pDllClass->SetFuncHandle((int)this,inf);
---------------
Q: Скан коды клавиш, где их взять? И почему они иногда разные?
----
A: ХЗ. Я использую такую таблицу:
//------
#define SC_KEY_ENTER 167 // OK
#define SC_KEY_GREEN 196 // green phone
#define SC_KEY_RED 197 // red phone
#define SC_KEY_MENU 180
#define SC_KEY_PREV 164 // Левая софт-клавиша
#define SC_KEY_NEXT 165 // Правая софт-клавиша
#define SC_KEY_MULTI 133 // *
#define SC_KEY_MULTI1 42 // Второй сканкод для звёздочки
#define SC_KEY_NUM 127 // #
#define SC_KEY_PENSIL 19 // ABC
#define SC_KEY_PENSIL1 18 // Второй сканкод для ABC
#define SC_KEY_LEFT 14
#define SC_KEY_RIGHT 15
#define SC_KEY_UP 16
#define SC_KEY_DOWN 17
#define SC_KEY_0 48
#define SC_KEY_1 49
#define SC_KEY_2 50
#define SC_KEY_3 51
#define SC_KEY_4 52
#define SC_KEY_5 53
#define SC_KEY_6 54
#define SC_KEY_7 55
#define SC_KEY_8 56
#define SC_KEY_9 57
#define SC_KEY_BS 1 // C
//------
Как видно из таблицы - клавиши * и ABC имеют 2 сканкода. Объяснить
это не могу, просто опытным путём было вычислено, что на некоторых
моделях и даже в разных эмуляторах сканкоды этих клавиш могут
быть такими.
---------------
Q: В программе используются комбинации клавиш. Как сделать так,
чтобы эти комбинации можно было в эмуляторе нажимать?
----
A: Правкой epoc.ini (%EPOCROOT%\\Epoc32\\Data\\epoc.ini).
В этом файле есть строки типа Keymap <вирт. код> <Имя клавиши>
Сюда можно добавлять свои клавиши.
У меня получилось повесить кнопки эмулятора на буквенные клавиши,
на остальные клавиши эмулятор почему-то не реагировал.
Виртуальный код клавиши A - 65, код клавиши Z - 90, остальные буквы
находятся в этом диапазоне. Вот названия кнопок эмулятора:
EOkKey
EClearKey
EApplicationKey
ESendKey // Зелёная трубка
EEndKey // Красная трубка
ELeftSoftKey
ERightSoftKey
EShiftKey // Карандаш
ELeftKey
ERightKey
EUpKey
EDownKey
ESideKey
EGripOpen
EGripClose
E1Key
E2Key
E3Key
E4Key
E5Key
E6Key
E7Key
E8Key
E9Key
E0Key
E*Key
E#Key
Таким образом, чтобы повесить, например, кнопку ОК на клавишу Y, нужно написать Keymap 89 EOkKey, зелёную трубку на O - Keymap 79 ESendKey . Теперь, нажав одновременно O и Y - получаем в эмуляторе нажатие клавиши GREEN+OK
---------------
Q: Хочу портировать программу! Что для этого нужно?
----
A: Консольные программы, написанные на C портируются достаточно легко - в поставке SDK есть порт библиотеки libc (%EPOCROOT%\\Epoc32\\include\\libc). Полное описание можно прочитать в топике Porting справки SDK (наберите это слово в поисковике справки).
Всего остального в стандартной поставке нет - так что не мечтайте написать в заголовке #include
и получить безошибочную компиляцию. Тем, кто хочет занимается портированием, рекомендуется полазить по sourceforge.net и поискать ещё какие-то порты программ под симбиан - вдруг повезёт, и окажется, что кто-то сделал за вас большой кусок дурной и нудной работы!
---------------