Condividi tramite


Allineamento

I problemi di allineamento in un'applicazione ODBC in genere non sono diversi da quelli presenti in qualsiasi altra applicazione. Ciò significa che la maggior parte delle applicazioni ODBC presenta alcuni o nessun problema con l'allineamento. Le penalità per il mancato allineamento degli indirizzi variano in base all'hardware e al sistema operativo e potrebbero essere di poco conto come una lieve riduzione delle prestazioni o come un errore di run-time irreversibile. Pertanto, le applicazioni ODBC e le applicazioni ODBC portabili in particolare devono prestare attenzione ad allineare correttamente i dati.

Un esempio di quando le applicazioni ODBC riscontrano problemi di allineamento è quando allocano un blocco di memoria di grandi dimensioni e associano parti diverse di tale memoria alle colonne di un set di risultati. Ciò è molto probabile quando un'applicazione generica deve determinare la forma di un set di risultati in fase di esecuzione e allocare e associare la memoria di conseguenza.

Si supponga, ad esempio, che un'applicazione esegua un'istruzione SELECT immessa dall'utente e recuperi i risultati da questa istruzione. Poiché la forma di questo set di risultati non è nota quando il programma viene scritto, l'applicazione deve determinare il tipo di ogni colonna dopo la creazione del set di risultati e associare la memoria di conseguenza. Il modo più semplice per eseguire questa operazione consiste nell'allocare un blocco di memoria di grandi dimensioni e associare indirizzi diversi in tale blocco a ogni colonna. Per accedere ai dati in una colonna, l'applicazione esegue il cast della memoria associata a tale colonna.

Il diagramma seguente mostra un set di risultati di esempio e il modo in cui un blocco di memoria potrebbe essere associato usando il tipo di dati C predefinito per ogni tipo di dati SQL. Ogni "X" rappresenta un singolo byte di memoria. (Questo esempio mostra solo i buffer di dati associati alle colonne. Questa operazione viene eseguita per semplicità. Nel codice effettivo, anche i buffer di lunghezza/indicatori devono essere allineati).

Binding by default C data type to SQL data type

Supponendo che gli indirizzi associati siano archiviati nella matrice Address, l'applicazione usa le espressioni seguenti per accedere alla memoria associata a ogni colonna:

(SQLCHAR *)       Address[0]  
(SQLSMALLINT *)   Address[1]  
(SQLINTEGER *)    Address[2]  

Si noti che gli indirizzi associati alla seconda e alla terza colonna iniziano in byte numerati dispari e che l'indirizzo associato alla terza colonna non è divisibile per quattro, che è la dimensione di un SDWORD. In alcuni computer questo non sarà un problema; su altri, ciò causerà una leggera riduzione delle prestazioni; in altri, causerà un errore di run-time irreversibile. Una soluzione migliore consiste nell'allineare ogni indirizzo associato sul limite di allineamento naturale. Supponendo che si tratti di 1 per UCHAR, 2 per SWORD e 4 per SDWORD, questo darebbe il risultato mostrato nella figura seguente, dove una "X" rappresenta un byte di memoria utilizzata e una "O" rappresenta un byte di memoria inutilizzato.

Binding by natural alignment boundary

Anche se questa soluzione non usa tutta la memoria dell'applicazione, non si verificano problemi di allineamento. Sfortunatamente, per implementare questa soluzione è necessaria una discreta quantità di codice, perché ogni colonna deve essere allineata singolarmente in base al suo tipo. Una soluzione più semplice consiste nell'allineare tutte le colonne in base alla dimensione del limite di allineamento più grande, che è 4 nell'esempio mostrato nella figura seguente.

Binding by largest alignment boundary

Sebbene questa soluzione lasci hole più grandi, il codice da implementare è relativamente semplice e veloce. Nella maggior parte dei casi, questa differenza è la penalità pagata nella memoria inutilizzata. Per un esempio che usa questo metodo, vedere Uso di SQLBindCol.