 |
CONVERSIONE CODICE PER CARBON
Carbon è in effetti solo una libreria, chiamata CarbonLib e prodotta da Apple, che modernizza ed estende il Toolbox Macintosh che eravamo arrivati a conoscere e ad amare. Amesso che l'estensione CarbonLib sia presente nella vostra Cartella Sistema di MacOS, o in quella dei vostri utenti, le vostre applicazioni gireranno in modo nativo su tutti i sistemi da 8.5 fino all'ultima versione Classic Mac OS [9.2 al momento]. In Mac OS X, le applicazioni Carbon girano in modo nativo.
L'esecuzione sotto Mac Os X di applicazioni PPC o 68K compilate con i rilasci precedenti di FutureBASIC invoca l'ambiente Classic (installato con Mac Os X) in modo da potere funzionare le applicazioni non native in un ambiente di compatibilità. La Versione 6 vi permette di eliminare questo strato di compatibilità quando eseguite le vostre applicazioni compilate. Bisogna però notare che l'intero IDE FB^3 non è ancora stato carbonizzato: quindi l'Editor, il Compilatore ed il Program Generator girano in modalità Classic sotto Os X. Nel frattempo, la vostra applicazione Carbon funzionerà allo stesso modo di qualunque altra applicazione normale di Mac OS X.
Detto questo, programmare per Carbon è tutto un nuovo mondo. Per incrementare i vantaggi del moderno sistema Mac OS X varie funzioni del toolbox sono state cambiate: quindi, se il vostro programma si basa pesantemente sul toolbox, dovrete prendere in considerazione alcune modifiche.
In effetti, non dovete credere che un programma che contiene migliaia di linee di codice giri senza problemi non appena si sceglie la voce di menu Esegui. Potete sognare, ma non scommettete la casa su questo sogno e non fate che questo sogno si transformi in un incubo, continuate invece leggere.
Segue una lista delle cose che dovrete controllare per vedere se il vostro codice ha bisogno di un aggiornamento...
|
Rilascio di stampa:
Parigi
25 feb. 2002
|
[ritorna all'inizio] |
Costanti di sistema
Eravamo abituati a leggere e scrivere certi valori nello spazio globale di sistema (low memory) usando peek e poke in quei valori di indirizzi noti come costanti di sistema.
Per esempio potevamo ottenere l'altezza corrente in pixel della barra dei menu con la seguente dichiarazione:
altz% = PEEK WORD (_mBarHeight)
o più facilmente usando la seguente abbreviazione:
altz% = {_mBarHeight}
Questa è una violazione diretta della memoria protetta che Mac OS X porta nelle nostre macchine e, come tale, questo genere di istruzione è incline a "piantare" la vostra applicazione non appena venga eseguita. Fortunatamente il Compilatore visualizza un avvertimento se state tentando di compilare un programma per Carbon che contiene delle costanti obsolete.
La soluzione è abbastanza semplice: per la maggior parte di questi valori globali, Apple fornisce ora delle funzioni specifiche. È solo questione di usarle. Seguendo il precedente esempio occorre ora usare la funzione del toolbox denominata GetMBarHeight. E tutto qui.
altz% = FN GetMBarHeight
Per il momento, occorre cercare la documentazione di Apple per tutte le funzioni disponibili di accesso a tali valori globali. Dei volontari stanno creando una lista che verrà presto pubblicata.
|
|
[ritorna all'inizio] |
Strutture Opache
In linea generale, tutto quello che appartiene al sistema è ora protetto. Questo rimane vero per molte cose che sono diventate molto note e molto usate dai programmatori Mac. In modo più specifico, strutture molto comuni come finestre, menu, controlli, ecc. sono diventati 'opache' in Carbon. La terminologia dice tutto: il programmatore non deve fare nessuna assunzione in riguardo all'organizzazione interna di queste strutture. Consequentemente, le vecchie tecniche di programmazione che hanno a che fare con queste sono destinate a fallire:
Accedere a valori usando la posizione (di solito usando pseudo-record);
Leggere/scrivere campi in veri record.
Entrambe le tecniche presuppongono una specifica disposizione interna delle strutture coinvolte, quindi sono buone candidate a piantarsi sotto Carbon.
Ancora, Apple ha fornito una soluzione: sono state rese disponibili delle funzioni accessorie di prelievo e di impostazione. Quindi, parte del lavoro di conversione consisterà nel trovare la funzione rilevante da usare in sostituzione nel vostro codice.
Esempio:
Inanzitutto, per ottenere il titolo di un dato menu, potevamo:
usare la constante predefinita _menuData come spostamento per ottenere la stringa Pascal situata in un menuHandle, come ad esempio la seguente:
titolo$ = PSTR$([menuHandle] + _menuData)
o definire un record a MenuInfo dichiarata negli header Apple come:
BEGIN RECORD MenuInfo
DIM menuID AS SHORT
DIM menuWidth AS SHORT
DIM menuHeight AS SHORT
DIM menuProc AS HANDLE
DIM enableFlags AS LONG
DIM menuData AS STR255
END RECORD
In seguito, dopo aver dichiarato il nostro handleMenu come un handle che punta ad una struttura MenuInfo (DIM handleMenu AS HANDLE TO MenuInfo) avremmo potuto scrivere:
titolo$ = menuHandle..menuData
Le tecniche precedenti funzionano ancora in PPC e 68K, ma non in Carbon, dove occorre invece usare l'accessorio funzione Toolbox GetMenuTitle:
dummy& = FN GetMenuTitle(menuRef,titolo$)
Ci sono un paio di cose interessanti da notare qui:
A parte il fatto che nessuna funzione esisteva prima di Carbon, il rifMenu può essere ottenuto con la regolare funzione GetMenuHandle anche usata per restituire un menuHandle in PPC e 68K. In secondo luogo, questa funzione ha aggiunto funzionalità in quanto restituisce sia il titolo di menu nel parametro titolo$ e un puntatore alla stringa titolo. Ciò permette di passare il risultato come parametro in un'altra funzione.
In modo analogo, istruzioni come handleMenu..menuWidth% devono essere cambiate in FN GetMenuWidth(handleMenu), e così via...
* Come considerazione a parte, potremmo notare che queste strutture sono definite nei file header Universal di Apple come puntatori o handle generici. Di solito, il loro nome termina con il suffisso ref. Ad esempio, noi siamo abituati a lavorare con controlhandle che sono handle che puntano ad un ControlRecord (^^ControlRecord). In Carbon, dobbiamo ora avere a che fare con ControlRef che sono semplici handle non tipizzati. Gran parte del Toolbox PPC è stato convertito in CarbonLib in modo tale che i cambiamenti siano gestiti quasi transparentemente e molte chaiamate Toolbox continuino a funzionare senza cambiamenti nel nostro codice.
|
|
[ritorna all'inizio] |
X-Files
Normalmente, senza il duro lavoro da parte di Staz Software, questa area tenebrosa sarebbe stata il vero incubo dei programmatori FB. Molte delle nuove funzioni FB riguardanti la gestione di file riguardano il vecchio ed obsoleto numero di riferimento a directory di lavoro. Credeteci o no, questo superato riferimento funziona ancora in Carbon con FutureBASIC!
In realtà, Staz Software ha riportato in vita le vecchie, studiate directory di lavoro. Tutto è fatto dietro le quinte, e se avete usato le normali istruzioni FutureBASIC per gestire l'apertura, la lettura e la scrittura dei file non noterete alcuna differenza. Questo è veramente incredibile!
I problemi potrebbero saltare fuori se avete mescolato le directory di lavoro gestite con FutureBASIC e le chiamate Toolbox. Questo è spesso il caso quando si passa un parameter block ad una funzione Toolbox file. Di certo esistono soluzioni. La più semplice è chiamare una funzione inclusa nel codice di esecuzione che gestisce la necessaria conversione prima di chiamare il Toolbox:
#IF CarbonLib
FN FBWDToPBWD(parameterBlock)
#ENDIF
Ovviamente, occorre assicurarsi che la chiamata Toolbox che si vuole usare sia ancora presente in Carbon (potrebbe essere stata rimossa).
In altre circostanze, beneficerete largamente dall'uso della raccomandata struttura File Spec. Questo richiede molte più cambiamenti nel vostro codice, anche se la Versione 6 introduce il Record FSSpec in molte delle sue funzioni file (la finestra di dialogo file può ora restituire tale struttura e si può usarla anche nell'istruzione OPEN).
Non solo avete a vostra disposizione queste due possibilità la Versione 6 arriva con un sacco di nuove routine file che possono gestire comuni compiti come verificare l'esistenza di un dato file, copiare e spostare file, anche scansionare un intera cartella. E questo funziona da 68K a Carbon in una maniera completamente trasparente.
In definitiva, sarete largamente assistiti nel processo di conversione.
|
|
[ritorna all'inizio] |
Appunti
La gestione degli appunti Clipboard è piuttosto differente in Carbon. Ma se sapete come copiare ed incollare, Ci arriverete in modo semplice. In molti dei vostri programmi, dovrete solo aprire i semplici file di esempio nel CD di FB^3 e copiare le funzioni appropriate nel vostro codice.
|
|
[ritorna all'inizio] |
Procedure di Chiamata di Ritorno (Callback)
Se siete affetti da procedure di chiamata di ritorno (callback), dovrete fare un po' di lavoro. Ma, onestamente, non così tanto!
Installare una procedura di chiamata di ritorno in Carbon richiede di fare uso, per tale lavoro, dell'appropriata funzione Toolbox. Inoltre deve essere "calcolato", il corretto punto d'entrata della procedura.
Potreste dover dichiarare la funzione d'installazione perché non tutte sono definite negli header di FB. Poichè seguono lo stesso schema, il processo è molto semplice. Prendiamo un filtro di finestra dialog come esempio.
per installare un filtro di finestra dialog serve la funzione Toolbox NewModalFilterUPP. Si può dichiarare questa funzione come:
#IF CarbonLib
TOOLBOX FN NewModalFilterUPP(PTR)=PTR
#ENDIF
Quando è ora di installare la vostra procedura, tutto quello che dovete fare è controllare se state compilando per Carbon quindi inviare il corretto punto d'entrata alla funzione di installazione. Questo può essere fatto con:
DIM myProc AS PROC
miaProc = PROC "mia proc filtro"
#IF CarbonLib
miaProc = FN NewModalFilterUPP( [miaProc + ¬ _FBprocToProcPtrOffset] )
#ENDIF
elementoPremuto = FN Alert(IDRis,miaProc)
Come già detto, la stessa tecnica si applica a tutte le procedure di chiamata di ritorno, in breve, l'unico vero segreto è quello di trovare la funzione Toolbox di installazione adatta.
|
|
[ritorna all'inizio] |
Aggiornamenti Schermo
Ora che il vostro programma compila senza errori, siete pronti a conoscere gli strani comportamenti. È possibile che il vostro programma esibisca un rallentamento inatteso o non riesca ad aggiornare correttamente lo schermo sotto OS X. Benvenuti alla caratteristica delle finestre bufferizzate.
In OS X, tutti gli ordini di disegno diretti verso una data finestra sono immagazzinati in un buffer provvisorio che è svuotato dal sistema alla successiva chiamata di WaitNextEvent. Ciò significa che per vedere effettivamente un aggiornamento sullo schermo la vostra applicazione deve chiamare HANDLEEVENTS. Questo non è sempre possibile quando il flusso del vostro programma è bloccato in un ciclo che redige le informazioni che tuttavia vorreste visualizzare. Per quel motivo, La Versione 6 introduce una nuova parola chiave che forza il sistema per svuotare il buffer in attesa. FLUSHWINDOWBUFFER immediatamente aggiornerà lo schermo in OS X, ma come effetto secondario noterete certamente un rallentamento. Mentre in qualunque altra versione del software di sistema FLUSHWINDOWBUFFER è inoffensivo potrebbe essere necessario sviluppare un'altra strategia strategia per quanto riguarda gli aggiornamenti dello schermo nei vostri programmi OS X.
Sul fronte aggiornamento, dovete sapere anche che le procedure InvalRect e ValidRect sono sparite dal Toolbox in Carbon. Sempre pronta ad aiutarci, la Versione 6 fornisce le funzioni incorporate nel codice d'esecuzione per facilitare il processo di conversione. Infatti, alterare il vostro codice dovrebbe essere una passeggiata, dovete solo sostituire la parola chiave (facoltativa) CALL con la parola chiave di FN e tutto continuerà a funzionare come di consueto:
Chambiare:
CALL InvalRect(r) // o semplicemente InvalRect(r)
in:
FN InvalRect(r)
|
|
[ritorna all'inizio] |
GrafPorts
Prima di Carbon noi potevamo considerare una GrafPort come una struttura inclusa nel Window record. Poiché il record GrafPort era il primo campo del Window record che entrambe le strutture iniziavano nella memoria alla stessa posizione e potevamo usare un puntatore window per riferirsi sia alla GrafPort che all'intero record Window.
Questo avrebbe funzionato:
GET WINDOW wndNum%,wndPtr&
CALL SetPort(wndPtr&)
Questo è da evitare in Carbon ed un viaggio gratuito nella Città dei Crash è assicurato. I puntatori Window e le GrafPort sono ora entità separate. Dovrete probabilmente controllare tutte le sezioni del vostro codice che hanno a che fare con le porte per assicurarvi di passare un vero GrafPort al Toolbox.
Notare che la Versione 6 vi aiuterà con funzioni potenziate WINDOW che possono restituire la CGrafPort o il WindowRef della finestra di output con l'aiuto di due nuove costanti.
WINDOW(_wndRef) restituisce l'opaco riferimento della finestra, mentre WINDOW(_wndPort) restituisce un puntatore alla GrafPort della finestra.
|
|
[ritorna all'inizio] |
Debug
In OS X, assegnare la memoria alla vostra applicazione non è più vostro compito. Questo genere di cosa è gestito dal sistema.
OK, questo è una cosa bella in particolare per l'utilizzatore finale. Tuttavia, per voi, come programmatore, diventano più difficili da rintracciare le perdite di memoria nei vostri programmi. Gli abituali strumenti di memoria non saranno d'aiuto in OS X. Può essere necessario forzare i vostri programmi carbonizzati per funzionare nell'ambiente Classic aggiungendo la seguente semplice istruzione nel vostro codice:
KILL RESOURCES "plst",0
Il motivo per questo è che le perdite di memoria si riveleranno rapidamente in Os 9 ma possono passare inosservate in Os X. Ovviamente, voi dovrete rimuovere questa dichiarazione quando svilupperete la vostra applicazione finale.
|
|
[ritorna all'inizio] |
Se avete altri problemi con la conversione del codice non esitate a contattarci, altri sono sicuramente nella vostra situazione e noi potremo completare questa lista di controllo e preparare qualche documento di Conversione per voi.
Fino ad allora, abbiate una buona esperienza di programmazione con la Versione 6.
|
|