Programmare cellulari Symbian UIQ in C++
=== appunti sparsi ===
Ultima revisione: 17 novembre 2006 (<new11-2>)

INDICE:

  1. Introduzione: quale SDK?
  2. Installazione e configurazione dell'SDK
  3. Compilare un'applicazione già pronta
    1. processo di compilazione di un programma c++ per Symbian
  4. Scrivere un'applicazione nuova partendo da un modello già pronto
  5. Scrivere un'applicazione utilizzando un ambiente grafico per posizionare i controlli
  6. Struttura di un'applicazione Symbian C++ per UIQ
  7. Distribuzione di un'applicazione per Symbian (file .SIS)
  8. Compilation target - dispositivo su cui girerà un programma
  9. Sigle degli emulatori (WINS, WINC, WINCW, UDEB,....)
  10. Note di programmazione
    1. Variabili globali
    2. Percorsi di compilazione
    3. Categorie di classi
    4. Naming conventions
    5. Gestione eccezioni
    6. Stringhe e descrittori
    7. server di sistema
    8. file di risorsa
  11. Tipi di applicazioni Symbian
  12. Struttura dei sorgenti di un'applicazione C++
  13. Differenze tra interfacce grafiche

Introduzione: quale SDK?

Per sviluppare programmi in C++ per cellulari Symbian UIQ è necessario scaricare un Source Development Kit (SDK), ad esempio dal sito SonyEricsson:

http://developer.sonyericsson.com/site/global/docstools/symbian/p_symbian.jsp

Oppure dal sito Symbian:

http://www.symbian.com/developer/sdks_uiq.asp

SonyEricsson p800, p900, p910 e Motorola a925/a1000 sono cellulari UIQ 2.x (il p800 e l'a925 sono 2.0, gli altri 2.1). Al momento con UIQ 3.0 c'e' solo il SonyEricsson p900. Bisognerà quindi scaricare l'SDK per UIQ 2.1 se si vuole scrivere un generico programma per UIQ. Se è specifico per il p800 servirà l'sdk per UIQ 2.0; se è per Motorola a1000 bisognerà scaricare anche l'SDK per l'a1000, che però da solo non può funzionare, in quanto costituisce un'aggiunta al generico SDK per UIQ, che quindi va comunque scaricato. Notare che esistono due tipi di SDK per UIQ 2.1: (winscw version) (225 MB) e (wins version) (168 MB) ; la prima serve per scrivere programmi usando l'IDE CodeWarrior, la seconda è per chi usa MS Visual Studio. Per chi usa... la linea di comando (!) dovrebbe essere indifferente, e forse preferibile il secondo, se non altro perche' si fa prima a scaricarlo.... ma a quanto pare se si vogliono far girare programmi in OPL sull'emulatore UIQ bisogna per forza usare il primo, per esempio. Quindi magari ci saranno anche altre differenze interessanti (dopotutto contiene 40 MB di roba in piu'); quindi, meglio usare la veriosne Winscw.

L'SDK per il Motorola a1000

L'SDK per a1000 risulta ancora in versione beta a un anno dall'uscita del cellulare.... Comunque. è scaricabile da motocoder.com (sito ufficiale) o da qui. Forse può essere utile anche l'SDK per l'a925 (UIQ 2.0), che sarà probabilmente più affidabile perché più testato. In ogni caso, motocoder.com è un ottimo punto di riferimento per chi vuole programmare l'a1000 (in C++, ma anche in J2ME; non supportano invece il PersonalJava, che probabilmente è implementato sull'a1000... per sbaglio, visto che non risulta dalle specifiche!), dal momento che hanno un ottimo servizio di assistenza per gli sviluppatori (ma bisogna ovviamente registrarsi al sito).

UIQ è il nome di una delle tante interfacce grafiche attraverso cui il sistema operativo Symbian dialoga con l'utente. Ci sono poi Series60 (cellulari senza touch-screen), Series80 e Series90 (Nokia communicators, con tastiere complete e senza touch screen) e altri.


CrezioInstallazione e configurazione dell'SDK

Dopo aver installato l'SDK per UIQ 7.0 (SonyEricsson p800 - Symbian 7.0) o UIQ 2.1 (SonyEricsson p910 - UIQ 2.1) (il che installa automaticamente anche PERL), supponendo di avere questi percorsi...

SDK UIQ 7.0:  e:\symbian\uiq_70

PERL:  e:\perl\bin

...ecco cosa bisogna fare per compilare uno degli esempi presenti nell'SDK:

SET PATH=c:\windows;c:\windows\command\;e:\PERL\BIN;e:\Symbian\UIQ_70\epoc32\stubs\tools
set PERL5LIB=e:\Symbian\UIQ_70\epoc32\tools\perllib

set epocroot=
devices -remove @

devices -add E:\Symbian\UIQ_70 E:\Symbian\UIQ_70 @UIQ_70:com.symbian.UIQ
devices -setdefault @UIQ_70:com.symbian.UIQ


Compilare un'applicazione già pronta

Portarsi dentro la cartella  E:\Symbian\UIQ_70\UIQExamples\BasicApp (o in quella di un qualsiasi altro esempio sotto  E:\Symbian\UIQ_70\UIQExamples\ ) e digitare:

bldmake bldfiles   (la sintassi completa sarebbe bldmake bldfiles @UIQ_70:com.symbian.UIQ , cioè occorrerebbe specificare il device)

Questo genererà dei file intermedi; bisognerà poi digitare:

abld build armi urel  (anche qui esiste una sintassi più completa: abld build thumb urel @UIQ_70:com.symbian.UIQ )

per compilare il programma per il telefono (si può usare anche abld build thumb urel) ; se si vuole invece compilare per l'emulatore, bisognerà scrivere abld build winscw udeb  se si usa CodeWarrior, altrimenti abld build x udeb (vedi in questa stessa pagina spiegazioni su THUMB/ARMI e WINC/WINS/WINSCW). Specificando udeb piuttosto che urel, verrà aggiunto nel codice compilato del codice utile per effettuare il debugging.

<new11-2>Su certi computer digitare il  comando abld build armi urel causa la comparsa di una valanga di errori, al punto che nemmeno facendo lo scrolling al contrario della finestra DOS (su sistemi NT) si riesce a risalire al primo errore!!
Questo porta a due consigli:
- Per rendere leggibili i primi errori anche in caso di output molto lungo, creare nella cartella dei sorgenti il file C.BAT, contenente le right:
call abld build armi urel (o equivalenti)
date  <--- serve solo a impedire che la finestra si chiuda subito; 

Cliccare poi col destro sul file, poi CREA COLLEGAMENTO, poi cliccare col destro sul collegamento e quindi su PROPRIETA';  nella finestra, scegliere la linguetta LAYOUT e immettere in ALTEZZA il numero di righe che la finestra DOS deve tenere in memoria. D'ora in poi, per compilare il progetto basterà fare doppio-click sul collegamento (che sarà utile rinominare in COMPILA.BAT)

- Il secondo consiglio risolve il probelema a monte: l'errore NON si deve verificare! Il motivo per cui si verifica è un'incompatibilità del compilatore GCC con l'ambiente DOS, nel quale non è tollerato l'uso di spezzare una linea di codice in più parti. Questo accade in moltissimi dei file .h dell'SDK (di qui la miriade di errori), e se ne ha un esempio nel primo file "incriminato" dalla sequela di errori:

..\\..\\..\\..\\EPOC32\\INCLUDE\\e32std.h:3685: `AType' was not declared in this scope
..\\..\\..\\..\\EPOC32\\INCLUDE\\e32std.h:3685: `AData' was not declared in this scope
..\\..\\..\\..\\EPOC32\\INCLUDE\\e32std.h:3685: `AData' was not declared in this scope
..\\..\\..\\..\\EPOC32\\INCLUDE\\e32std.h:3685: template argument 1 is invalid
..\\..\\..\\..\\EPOC32\\INCLUDE\\e32std.h:3685: stray '\' in program
..\\..\\..\\..\\EPOC32\\INCLUDE\\e32std.h:3686: warning: ANSI C++ forbids declaration `AName' with no type

Intorno alla riga 3685 del file e32std.h troviamo infatti:

#define DECLARE_ROM_ARRAY( AName, AData, AType )  \  
       const TFixedArray<AType,(sizeof(AData)/sizeof((AData)[0]))>& 
\  
            AName = *(reinterpret_cast<const TFixedArray<AType, 
\  
                           (sizeof(AData)/sizeof((AData)[0]))>* > (AData))

L'errore è causato da quelle 3 " \  "... e dalla libreria sbagliata cygwin.dll in c:\windows\system32 sul vostro PC: eliminando il file si potrebbe risolvere il problema; ma siccome se il file sta lì ci sarà pure un motivo, meglio limitarsi ad aggirare il file, rinominadolo e mettendo al suo posto quello conetnuto in  C:\Symbian\UIQ_70\epoc32\gcc\bin )

Fonti:
http://www.simkin.co.uk/cgi-simkin/mwforum/topic_show.pl?tid=91
http://gcc.gnu.org/ml/gcc-patches/2004-08/msg01869.html
http://discussion.forum.nokia.com/forum/showthread.php?p=258308#post258308
 (risolutivo insieme al successivo)
http://discussion.forum.nokia.com/forum/showthread.php?t=5268  (permette di non cancellare cygwin.dll, bypassandolo tramite la variabile di ambiente PATH)

Il risultato della compilazione, il file BasicApp.App, verrà memorizzato in E:\Symbian\UIQ_70\epoc32\release\thumb\urel (oppure E:\Symbian\UIQ_70\epoc32\release\armi\urel o E:\Symbian\UIQ_70\epoc32\release\winscw\urel , a seconda del comando usato prima ).

Copiando questo file (da thumb\urel o armi\urel, sicuramente NON da winscw\urel, in cui si trova il prgramma che funziona solo sull'emulatore) sul telefono, in c:\system\apps\BasicApp , l'applicazione dovrebbe risultare installata sul telefono ma non ancora avviabile: manca il file di risorse, che ha origine dal file BasicApp.rss presente nella cartella BasicApp, e che risulta in un file BasicApp.rsc salvato nella cartella E:\Symbian\UIQ_70\epoc32\data\z\system\APPS\BASICAPP.

Si potrebbe quindi riassumere il processo di compilazione di un programma c++ per Symbian in un file batch come questo:

(modificare opportunamente il nome dell'applicazione e  la parte "E:\symbian\"):

e:\
cd E:\Symbian\UIQ_70\UIQExamples\BasicApp
bldmake bldfiles
(bldmake bldfiles @UIQ_70:com.symbian.UIQ se l'SDK di default è un altro)
abld build armi urel (abld build armi urel @UIQ_70:com.symbian.UIQ se  l'SDK di default è un altro)
copy E:\Symbian\UIQ_70\epoc32\release\armi\urel\%1.app .
copy
E:\Symbian\UIQ_70\epoc32\data\z\system\APPS\BASICAPP\%1.rsc .

Le ultime due righe copiano nella directory corrente i file generati, che andranno copiati sul cellulare nella cartella system\APPS\BASICAPP\.
In realtà i file da copiare alla fine potrebbero essere di piu', di meno o in altre posizioni, a seconda del progetto... Ma piu' o meno ci siamo.

Per avviare l'emulatore:

epoc @UIQ_70:com.symbian.UIQ

o doppio click sul file EPOC.EXE desiderato:

Symbian\UIQ_21\epoc32\release\armi\urel\epoc.exe


Scrivere un'applicazione nuova partendo da un modello già pronto <new11-2>

Tramite questo script in Perl è possibile creare automaticamente lo scheletro di un'applicazione di base, che non fa niente se non comparire sullo schermo e mettere a disposizione un menu con l'unica voce EXIT. Sta allo sviluppatore poi riempirla come meglio crede, per trasformarla nell'applicazione desiderata.
DOWNLOAD UIQ Wizard


Scrivere un'applicazione utilizzando un ambiente grafico per posizionare i controlli <new11-2>

Per scrivere un'applicazione per un ambiente grafico come Symbian (o Windows) è utile disporre di un ambiente che permetta di collocare, appunto, graficamente, i vari controlli dell'applicazione. Si può usare ad esempio OpenQUB oppure UBIQLIPSE. Il secondo è un plugin per Eclipse (che non sono riuscito ad installare...), il primo è un programma in Java, quindi per farlo funzionare dovete avere correttamente installato il Java Runtime Environment (JRE) sul vostro PC.

Ecco come appare l'ambiente OpenQUB:

OpenQUB screenshot



Scrivere un'applicazione usando un ambiente integrato (IDE)

Un'ambiente integrato di sviluppo (Integrated Development Environment - IDE) è un programma che permette di editare e compilare sorgenti tramite click del mouse anzichè tramite comandi DOS. Un IDE è veramente completo se permette, oltre che di scrivere sorgenti, di collocare visivamente i controlli di un'applicazione, come si fa ad esempio con OpenQUB, che però non consente (mi pare) di compilare il codice prodotto automaticamente a partire dall'interfaccia creata.
Esistono vari ambienti di sviluppo per scrivere programmi Symbian C++: Metrowerks CodeWarrior, Microsoft Visual C++, Borland C++ (tutti, a quanto pare, a pagamento) e, ultimamente, Carbide.c++ (i link cambiano spesso su www.forum.nokia.com : se il link non funziona, cercare Carbide Development Tools for Symbian OS C++; la versione Express è quella gratuita) completamente gratuito. Questo IDE si appoggia alla struttura dell'ambiente di sviluppo "generico" noto come Eclipse; è in pratica una personalizzazione di Eclipse fatta da Nokia per permettere di programmare facilmente in Symbian C++ per Series60, ma che funziona anche per altre varianti Symbian, come UIQ.
Per una guida più dettagliata a Carbide si rimanda alla pagina di approfondimento.


Struttura di un'applicazione Symbian C++ per UIQ

All'interno della cartella \Symbian\UIQ_70 dell'SDK si trova una cartella chiamata UIQExamples (o simile) che contiene appunto programmi di esempio completi di sorgente, che possono essere modificati a piacimento per impratichirsi nell'ostica programmazione C++ Symbian. Dalla cartella dell'applicazione HelloWorld si evince qual è la struttura di una generica applicazione:

Dalla compilazione dei file .cpp risultano dei file .o, che vengono poi collegati (link) tra loro in modo da formare, alla fine, il file .app, che non è un eseguibile vero e proprio, ma una libreria (DLL). E' tuttavia possibile specificare che il compilatore debba produrre un eseguibile vero e proprio, che avrà estensione .exe e sarà privo di interfaccia grafica. <new09-02>


Distribuzione di un'applicazione per Symbian (file .SIS)

Una volta certi che l'applicazione funziona, bisognerà creare un file SIS per distribuirla, dopo aver richiesto un UID univoco alla Symbian ([email protected]). Per creare il file sis, basta digitare

makesis nomefile.pkg

dove nomefile.pkg è un file di testo strutturato come segue (maggiori dettagli nella documentazione dell'SDK sul vostro hard disk: E:/Symbian/UIQ_70/Documentation/Packages/UIQ_70/sdl/ToolsAndUtilities/Installing-ref/PackageFileFormatReference.guide.html):

#{"BasicApp"},(0x12345678),7,0,0,TYPE=SA    
Prima riga, obbligatoria; cambiare il nome dell'applicazione, e sostituire 0x12345678 col suo UID

(0x101F617B), 2, 0, 0, {"UIQ20ProductID"}
Seconda riga, obbligatoria: il primo numero è il ProductID, e deve corrispondere con la strimga successiva.

"\Symbian\UIQ_70\epoc32\release\thumb\urel\BasicApp.app"-"!:\system\apps\basicapp\basicapp.app"
Copia il file da \Symbian\UIQ_70\epoc32\release\thumb\urel\BasicApp.app (sul PC) a !:\system\apps\basicapp\basicapp.app (sul cellulare; il "!" indica che il drive può essere specificato dall'utente).

"\Symbian\UIQ_70\epoc32\data\z\system\apps\BasicApp\BasicApp.rsc"-"!:\system\apps\basicapp\basicapp.rsc"
Analoga alla precedente.


Compilation target - dispositivo su cui girerà un programma
da http://www.ent.mrt.ac.lk/dialog/Pages/News/Presentation1.pdf

Il Sistema Operativo Symbian gira nativamente su processori ARM, e supporta tre tipi di eseguibili ARM, chiamati Application Binary Interfaces (ABIs): ARM4, ARMI e THUMB

  1. i programmi compilati per ARM4  utilizzano il set di istruzioni ARMv4, che è quello "di base". <new09-02>

  2. i programmi compilati per THUMB utilizzano il set di istruzioni THUMB a 16 bit, sottoinsieme dell'ARMv4T, utilizzando l'istruzione BX (vedi sotto); con quetso set si ha un'ottimizzazione delle dinensioni dell'eseguibile. <new09-02>

  3. i programmi compilati per ARMI utilizzano il set di istruzioni ARM, sottoinsieme di ARMv4T, utilizzando l'istruzione BX; con questo set si ha un'ottimizzazione della velocità di esecuzione. <new09-02>

L'istruzione BX permette di passare, nel corso dell'esecuzione del programma, dall'uno all'altro dei due subset di istruzioni ARM e THUMB.

Il codice del Sistema Operativo presente in ROM può essere stato compilato in uno qualunque dei 3 set di istruzioni, e dal momento che il subset ARMI è compatibile con tutti e tre, è consigliabile compilare codice per subset ARMI.

E' possibile anche compilare un programma affincé giri sull'emulatore anziché sul dispositivo reale, nel qual caso il target da specificare sarà WINS o WINSCW (vedi paragrafo Sigle degli emulatori)

Tra emulatore e dispositivo reale esiste una differenza nella risoluzione dei timer: sull'emulatore è di 1/10 di secondo, sul dispositivo è di 1/64, e occorre tenerlo presente nel testare i programmi sull'emulatore.

L'istruzione "semplice"  abld build , senza ulteriori parametri, compila  tutte le 8 varianti disponibili tra emulatore e dispositivo reale (ARM, THUMB, ARMI, WINS, in verisone UREL o UDEB) <new09-02>


Sigle degli emulatori

WINC:

WINSCW:

WINS: Come WINSCW, ma progettato Per Microsoft Visual C++


Note di programmazione

Sigle:

Ogni applicazione standard per Symbian, ovvero un file .APP, è in realtà una DLL, una Dynamic Link Library o (Libreria a Collegamento Dimamico); ossia, non è un programma indipendente, ma una raccolta di funzioni utilizzate da un altro programma (in questo caso, dal Sistema Operativo Symbian, immagino... TBD). Un'applicazione Symbian compilata  invece per l'emulatore anziché per il dispositivo reale, è in realtà una DLL di Windows.

Variabili globali

Il S.O. Symbian non permette l'uso di dati statici nelle DLL (quindi nei fille .APP), mentre Windows sì, perciò nelle applicazioni Symbian per il dispositivo reale non si posson usare dati statici (quindi variabili gobali), mentre in quelle per l'emulatore sì (perché è Windows a usare la libreria, non Symbian). (L'unica eccezione sono gli eseguibili Symbian (.exe), che non essendo librerie possono far uso di dati statici).  Questo rende impossibile l'utilizzo di variabili globali; siccome però il loro uso in certi casi può tornare utile, Symbian consente in realtà di utilizzarle, ma solo all'interno di un thread: si parla di Thread Local Storage, TLS), cui si può accedere tramite la classe Dll. TLS è un semplice puntatore TAny*. (cfr. Symbian OS: From ANSI C/C++ To Symbian C++ v1.0) - se il link non funziona, cercare il titolo nel documento nella casella SEARCH di http://www.forum.nokia.com/). Questa limitazione non esiste per i file .EXE, in genere usati per scrivere Server.

Categorie di classi

Le classi sono divise in 4 tipi: T, C, R e M; ogni classe scritta dallo sviluppatore dovrà iniziare con la lettera corrispondente, per permetterne un'immediata classificazione "a vista" da parte di altri sviluppatori. Il significato delle iniziali è il seguente (cfr. Symbian OS: From ANSI C/C++ To Symbian C++ v1.0):

Notare che benché le classi T possano essere create sullo stack, questa non è una buona idea. Sul dispositivo reale lo stack ha dimensioni molto ridotte (8KB per default) e alcune classi T occupano molto spazio (TFileName, ad esempio, occupa più di 512 byte). Dal momento che l'emulatore utilizza lo stack di Windows NT, che può arrivare fino a 8 MEGAbyte, non ci si accorgerà di eventuali problemi di memoria finche' non si proverà il programma sul dispositivo reale. Al contrario, sul dispositivo reale, come detto, lo stack è molto ridotto; le classi più "voluminose" andranno memorizzate nell'heap; in questo caso, però, la memoria allocata per la classe dovrà poi essere liberata manualmente, al contrario di quanto accade con le classi sullo stack, la cui memoria viene deallocata automaticamente all'uscita dalla classe.

Le classi vengono create nello heap tramite new.

Naming conventions -convenzioni per l'assegnazione dei nomi a classi e variabili.

Le classi statiche non hanno nessun prefisso e iniziano con una lettera maiuscola.

Gestione eccezioni ("leaves")

Non esistono eccezioni come in C++ "classico", sotto Symbian si usano le leaves, che possono essere generate direttamente da una funzione (col metodo User::Leave(), equivalente al Throw del C++), o da una struttura di TRAPPING (implementata tramite TRAP e TRAPD, vedi più avanti). Si fa quindi un "trapping leaves" invece che un "catching exceptions". Ogni metodo che prevede un "leave" deve avere un nome che finisce per "L"(cfr. Symbian OS: From ANSI C/C++ To Symbian C++ v1.0), è così pure i metodi che lo chiamano. Tuttavia non tutti i metodi devono necessariamente effettuare il trapping, che è comunque effettuuato da Symbian OS.
Symbian OS gestisce in modo particolare le "exceptions" del processore, tramite la classe RThread: se una di queste exceptions non è catturata dal programma, il Sistema la catturerà emettendo un panic con codice KERN EXEC 3.
Oltre ai leaves esistono infatti  i panics, che non possono essere intercettati e causano l'interruzione immediata del thread. Si può generare  un panic con User::Panic.

TRAP-TRAPD:
Per intercettare un "leave" occorre che la funzione che lo genera sia gestita in un modo particolare; supponendo che FunzioneL() sia la funzione che può generare un leave (bisogna quindi aggiungere una L alla fine del nome), avremo:

void FunzioneL()
 {
 CExample* myExample = new CExample;
 if (!myExample) User::Leave(KErrNoMemory);
 // leave used in place of return to indicate an error
 
 // do something
 myExample->iInt = 5;
 testConsole.Printf(_LIT("Value of iInt is %d.\n"),myExample->iInt);
 // delete
 delete myExample;
 }

Per intercettare quando un leave proviene da questa funzione, bisogna chiamare la funzione tramite un TRAP:

TInt E32Main()
 {
 testConsole.Title(); //Scrive il titolo
 testConsole.Start(_LIT("Example")); // start a new "test"

 // Variabile associata al "leave"
 TInt r=0;
 // Chiama la funzione: se esce con un "leave",
 // il codice del "leave" e' messo in r.
 TRAP(r,FunzioneL());
 // Processa la variabile che potrebbe contenere il codice del leave:
 if (r)
  testConsole.Printf(_LIT("Errore: codice leave=%d"), r);

 testConsole.End(); // finisce
 testConsole.Close(); // chiude
 return KErrNone; // ritorna
 }

Quando si ha un leave, la funzione ritorna subito, senza dare il tempo di liberare eventuale memoria allocata; questo causerebbe un "memory leak" (spreco di memoria), che non è accettabile in un dispositivo con memoria limitata come un cellulare. La gestione dei leave è quindi  strettamente connessa con la gestione della  memoria (cleanup).

Esiste infatti uno stack appositamente dedicato all'allocazione e deallocazione di memoria per le risorse richieste dal programma; questo perché, come detto, quando una funzione termina con un leave non dà tempo di liberare la memoria coi metodi tradizionali; esempio:

CDemo* demo = new CDemo;
DangerousOperationL();
delete demo;

Se la funzione esce con un leave, l'istruzione delete non verrà mai eseguita! Ecco quindi il modo corretto con cui va chiamata una funzione:

CDemo* demo = new CDemo();
CleanupStack:: PushL(demo); // Allocazione sullo stack
DangerousOperationL();
CleanupStack:: PopAndDestroy()  // deallocazione: se il flusso di programma non arriva 
                                // qui (a causa di un leave), ci pensa il sistema a
                                // cancellare il primo elemento dallo stack con un 
                                //pop & destroy.

Bisogna quindi ricordarsi di mettere sul Cleanup Stack qualunque oggetto "pericoloso" creato tramite New o NewL. NewLC crea invece direttamente nel Cleanup Stack.
Bisogna fare attenzione però a non cancellare l'oggeto sbagliato: se per esempio l'oggetto viene messo in un array, esso dovrà essere deallocato dal cleanup dell'array, e se si tentasse un PopAndDestroy DOPO che l'array ha deallocato, si deallocherebbe l'oggetto sbagliato! Se però per fare il pop si usa pop(object), nella versione di debug ci sarà un PANIC se si tenta di deallocare un oggetto che non corrisponde a quello sullo stack (cosa che non succede nella  versione "release").

Il Cleanup Stack può essere usato anche per chiudere le risorse: se si mette una risorsa sul CS con CleanupClosePushL, il successivo PopAndDestroy(), oltre a deallocarla, la chiuderà anche.

Stringhe e descrittori

Al posto delle stringhe si usano i descrittori, che sostituiscono le stringhe null-terminated, gli array di byte e gli array di puntatori.

Le applicazioni Symbian sono strutturate per lavorare con server di sistema, ai quali richiedono/inviano dati tramite le API di sistema. I dati possono essere scambiati in modo sincrono o  asincrono.
Il Symbian OS è organizzato secondo una struttura Client/Server: il kernel del S.O. è minimo, la maggior parte dei servizi sono forniti da server che a esso si collegano e a cui si collegano le varie applicazioni. I server forniscono delle classi che rendono trasparente l'utilizzo del sistema client-server.

I file di risorsa sono obbligatori, perché servono a definire l'interfaccia visibile all'utente. Sono utili anche per facilitare la traduzione dei programmi in lingue diverse (localization), e perché possono contenere stringhe utilizzate dal programma, che così vengono caricate in memoria solo quando serve.

I vari controlli disponibili in una GUI derivano tutti dalla classe CCoeControl. Esiste un IDE gratuito chiamato Open QUB che permette di creare interfacce grafiche usando il mouse anziché scrivendo codice a mano (non l'ho ancora provato, ma se funziona è decisamente un tool molto utile).

Le applicazioni Symbian sono in genere a thread singolo; possono anche essere multi-thread, ma tale pratica è sconsigliata.

Symbian OS è un S.O. con multitasking non-preemptive; gli eventi vengono pianificati (scheduled) da Active Scheduler e gestiti (handled) da Active Objects.

Ogni applicazione per S.O. Symbian deve avere un identificativo univoco, chiamato UID. Per lo sviluppo si possono usare a piacere tutti gli UID compresi tra 0x01000000 e 0x0fffffff, ma per applicazioni da distribuire al pubblico occore farsi dare un UID univoco dalla Symbian ([email protected]). L'utilizzo di un  UID "sbagliato" causa il classico errore "NOT FOUND" all'avvio dell'applicazione. L'UID dell'applicazione non va confuso con il ProductID, un altro UID che specifica su quale variante di Symbian  girerà un certo programma.

Scrivere un'applicazione Symbian OS completamente in C anziché C++ è difficile o quasi impossibile, ma se si hanno dei vecchi sorgenti C da "riutilizzare", si possono eventualmente implementare come server, in quanto i server supportano le variabili globali, presenti nel linguaggio C. Si tratta quindi solo di aggiungere del codice per gestire i messaggi tra server e applicazioni. Il risultato finale sarà comunque un'applicazione piuttosto lenta.

Nei programmi per Symbian non si possono usare percorsi relativi per i file, bisogna sempre specificare il drive (o usare la speciale implementazione Symbian di STDLIB).

Lo sviulppo di applicazioni per WINC è analogo a quello per WINS:


Percorsi di compilazione

Emulatore

Compilando un programma per l'emulatore WINS/WINSCW anziche' per il dispositivo reale, i files ottenuti verranno memorizzati in percorsi differenti.

Applicazioni con interfaccia grafica possono avere o non avere un file AIF associato, che ne definisce, tra le altre cose, l'icona. In mancanza di tale file, viene usata un'icona di default, ma l'applicazione non potrà aprire nuovi file (??tbc??) è non può essere embedded.

Per avviare il file .APP ottenuto occorre lanciare rispettivamente uno di questi eseguibili, che avvierà l'emulatore adatto da cui avviare l'applicazione:

I programmi compilati per WINC vengono messi in \epoc32\release\winc\variant\


Tipi di applicazioni Symbian

Sui dispositivi reali, le applicazioni prive di interfaccia grafica hanno suffisso .EXE; tuttavia, esse non possono essere avviate sugli emulatori. Quando però un'applicazione console viene compilata per un emulatore, essa viene dotata di codice aggiuntivo che permette di avviarla direttamente da Windows (da una finestra DOS o da Esplora Risorse). Per sviluppare applicazioni per console, bisogna compilarle per WINC, ottenendo un file .EXE. Questo file riceve il controllo da E32Main(), che non ha parametri, quindi per leggere eventuali parametri della linea di comando bisogna usare una API Symbian: la cosa migliore è usare la classe CCommandLineArguments. Si può scrivere anche un'eseguibile .EXE per Windows invece che per console, che farà riferimento a librerie compilate e testate sotto WINC per accedere a dati Symbian. (cfr. The WINC build target in Build tools guide). Gli UID non hanno alcuna importanza quando si compila per WINC. .Un eseguibile .EXE per WINC va avviato specificando non il solo nome del file, ma l'intero percorso.
Per compilare un'applicazione come .EXE, ocorre un file MMP contenente le righe TARGETTYPE exe  e  UID 0; un esempio di file MMP per un EXE è il seguente:

TARGET HelloWorld.exe
TARGETTYPE exe
UID 0
SOURCEPATH .
SOURCE HelloWorld.cpp
USERINCLUDE .
USERINCLUDE ..\CommonFramework
SYSTEMINCLUDE \Epoc32\include
LIBRARY euser.lib

Programmi che fungono da server sono compilati come EXE, ma non possono essere avviati sugli emulatori, per i quali vanno compilati come DLL

Vengono compilate con suffisso .DLL, e in genere  messe per default nelle stesse directory degli EXE, ma il percorso puo' venir cambiato dallo sviluppatore.

<new09>Il p800 supporta i set di istruzioni ARMI e THUMB: il primo è a 32 bit, il secondo a 16 bit. In entrambi i set ci sono istruzioni che consentono di passare dall'uno all'altro modo.

I programmi THUMB sono piu' piccoli ma piu' lenti.

<new09>Un programma compilato  in RAM ha questa struttura:
E32 executable image header (0x7C bytes)
Code section Text section (code and constant data)
Import table
Export table
Data section (initialised data)
Import section
Code relocation section
Data relocation section

<new09>Compilato per la ROM, invece, ha questa struttura:
E32 ROM image header (0x64 bytes)s
Code section Text section (code and constant data)
Data section (initialised data)
Export table
DLL reference table

<new09>(rif. http://www.virusbtn.com/virusbulletin/archive/2005/09/vb200509-symbian-os.dkb)

<new09>Il codice eseguibile inizia all'inicio della Text Section.


Ancora da tradurre:
Struttura dei sorgenti di un'applicazione C++
Struttura filesorgenti in un'applicazione Symbian C++(immagine tratta da NewLC.com)

Symbian C++ programs are written, of course, in C++. So you have many ordinary C++ files. For a GUI application we usually need at least four of them: the application, the model, the controller and the view. So we have at least four C++ files HelloApp.cpp, HelloDocument.cpp, HelloAppUi.cpp and HelloView.cpp.

They could all be stored in a single file, but usually you place each class in a couple of files. A file stores the declaration of a class, and have extension .h, and a file stores the implementation on a class, with the usual .cpp extension. So we have also HelloApp.h, HelloDocument.h, HelloAppUi.h and HelloView.h. When you compile such files, you got a .o binary from each .cpp. Then you link together the .o to obtain an executable, with extension .exe or an application (a dll) with extension .app.

GUI application also separate code and resources. Resources are a special format Symbian-specific, that will be compiled by the Symbian resource compiler, the rcomp. A resource file in source form has extension .rss, so we can have also Hello.rss among the sources of our program.

You can have more than one .rss and place part of the resources in a common file, included from many .rss. A resource inclusion file has usually extension .rh. When you compile a resource file, you got a binary .rsc, that must be included in the deploy of your program. The .app will access to the .rsc.

Now an important case: some declarations in the .rss must be shared between the .rss and the .cpp. And, to make thing more complicated, the shared part can be written by and or generated from the compiled .rss. You place the hand written part that must be included both in a .cpp and a .rss in a file with extension .hrh. Such a file usually contains only enumeration, since this is the format that is understood both by the C++ and the resource compiler. After compiling a resource, the resource compiler generates some values that must be further included in a source .cpp. The generate file has an extension .rsg. Note that a .rsg is a source file (ascii, not binary) but it is generated, not hand-written.

Lastly we remember there are also .pan containing panic codes, and .loc, .lo1 etc, containing localization declarations.


Differenze tra interfacce grafiche <new11>
Il sistema operativo Symbian è caratterizzato dal fatto di essere installato su dispositivi molto diversi tra loro per quanto riguarda l'interfaccia utente: esostono dispositivi con touchscreen,
touchscreen
oppure con tastiera QWERTY completa più speciali tasti funzione aggiuntivi ("CBA Buttons"),
nokia-qwerty
 o con la tipica tastiera telefonica con 10 tasti numerici e pochi altri  tasti
nokia-series60

Nel primo caso si parla di interfaccia UIQ (Motorola a920/a925/a1000, SonyEricsson p800/p900/p910/p990, BenQ p30), nel secondo di nei Series80 (Nokia Communicator), e nell'ultimo di Series60.
Tutte queste varianti hanno in comune un "framework" grafico chiamato UIKON/EIKON: un'applicazione che si basa solo su questo framework potrà quindi girare su qualunque variante di interfaccia grafica.
Ognuna di queste interfacce ha però anche un suo framework ben distinto:
AVKON (S60)
AIKON (S80 1.0)
CKON (S80 2.0)
QIKON (UIQ)


Links:

Ricerca tra le FAQ della Symbian: http://www3.symbian.com/faq.nsf/SearchAll?OpenForm

SDK per SonyEricsson P800/P900/P910: http://developer.sonyericsson.com/site/global/docstools/symbian/p_symbian.jsp

Codici d'errore Symbian OS: http://www.newlc.com/article.php3?id_article=117

Far creare un LOGFILE a un'applicazione: http://www.newlc.com/article.php3?id_article=131

Far mostrare versione estesa di un errore all'emulatore (e forse anche al cellulare stesso): http://www.newlc.com/article.php3?id_article=150

Sorgenti gratuiti per Symbian (c++ e Java)

Compilare senza IDE:
http://www3.symbian.com/faq.nsf/0/E961EA6C04EA6BF080256EDD0055D063?OpenDocument
http://www.newlc.com/article.php3?id_article=497
http://www.newlc.com/article.php3?id_article=463
http://pf128.krakow.sdi.tpnet.pl/symbdev/  (cambiato in  http://www.mikolaj.zalewski.pl/symbdev/)

Tutorial Symbian c++: http://www.pocketvnc.com/tutorials/symbian/symbian.aspx

Symbian Example (sito con molte chiacchiere per s60, ma utile): http://symbianexample.com/projectwizard


TIPS & TRICKS
Differences between uiq2.1 and s60 compilation:

S60:
Compiling resources...
epocroot = \Symbian\6.1\Series60\
* C:\Symbian\6.1\Series60\..\Shared\epoc32\gcc\bin\cpp.exe

and UIQ2.1:
Compiling resources...
epocroot = \Symbian\UIQ_21\runtime\
* cpp -undef -C -I C:\Programy\Symbian1\group

As you can see whiile in S60 is valid path to cpp.exe file, in uiq is only "cpp"... The plugin is incomplete    

-----------
1) To compile from command prompt:
Run "Visual Studio .NET\Vc7\bin\vcvars32.bat"
This sets path environment variable, so that you can compile programs from Command Prompt. This is a totally VS .NET related thing and is told in VS .NET Help docs.

Now you can do:

bldmake bldfiles
abld build wins udeb

and finally start emulator and test your program as described in S60SDK Help -> Symbian OS -> Symbian OS v6.1 Edition for C++ -> Developer's Guide -> Hands on

2) To run and debug from VS .NET environment
bldmake bldfiles
abld makefile vc6
open project file
(This all is told in S60SDK Help -> Symbian OS -> Symbian OS v6.1 Edition for C++ -> Developer's Guide -> Hands on)

After this you should disable C++ Exceptions as told in this discussion thread (Project -> Properties -> C/C++ -> Code Generation -> Enable C++ Exceptions -> No)

Finally, to be able to run and debug your examples, set
Project -> Properties -> Debugging -> Command to
Symbian\6.1\Series60\Epoc32\Release\wins\UDEB\EPOC.EXE

And that's it, most of the things seems to compile




Indice degli appunti di programmazione:

Appunti di programmazione in ambiente Symbian C++
Usare Carbide.c++
Importare un progetto in Carbide.c++ da un file .MMP
Compilare un eseguibile Symbian .exe multiplatform
Appunti di programmazione PersonalJava
Compilare un'applicazione PersonalJava, creare i file .APP, .AIF e .TXT per lanciarla, e installarla sull'emulatore.  
Appunti di programmazione Java Midlet