Partager via


Alignment

Les problèmes d’alignement dans une application ODBC ne sont généralement pas différents de ceux d’une autre application. Autrement dit, la plupart des applications ODBC présentent peu ou pas de problèmes d’alignement. Les pénalités pour ne pas aligner les adresses varient selon le matériel et le système d’exploitation et peuvent être aussi mineures qu’une légère pénalité de performances ou aussi majeure qu’une erreur d’exécution irrécupérable. Par conséquent, les applications ODBC et les applications ODBC portables en particulier doivent être prudents pour aligner correctement les données.

L’un des exemples de cas où les applications ODBC rencontrent des problèmes d’alignement est lorsqu’elles allouent un grand bloc de mémoire et lient différentes parties de cette mémoire aux colonnes d’un jeu de résultats. Cela se produit probablement lorsqu’une application générique doit déterminer la forme d’un jeu de résultats au moment de l’exécution et allouer et lier la mémoire en conséquence.

Par exemple, supposons qu’une application exécute une instruction SELECT entrée par l’utilisateur et extrait les résultats de cette instruction. Étant donné que la forme de ce jeu de résultats n’est pas connue lorsque le programme est écrit, l’application doit déterminer le type de chaque colonne une fois le jeu de résultats créé et lier la mémoire en conséquence. La méthode la plus simple consiste à allouer un grand bloc de mémoire et à lier différentes adresses dans ce bloc à chaque colonne. Pour accéder aux données d’une colonne, l’application convertit la mémoire liée à cette colonne.

Le diagramme suivant montre un exemple de jeu de résultats et comment un bloc de mémoire peut être lié à celui-ci à l’aide du type de données C par défaut pour chaque type de données SQL. Chaque « X » représente un octet de mémoire unique. (Cet exemple montre uniquement les mémoires tampons de données liées aux colonnes. Cela s’effectue par souci de simplicité. Dans le code réel, les mémoires tampons de longueur/indicateur doivent également être alignées.)

Binding by default C data type to SQL data type

En supposant que les adresses liées sont stockées dans le tableau d’adresses , l’application utilise les expressions suivantes pour accéder à la mémoire liée à chaque colonne :

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

Notez que les adresses liées aux deuxième et troisième colonnes commencent par des octets impairs et que l’adresse liée à la troisième colonne n’est pas divisible par quatre, ce qui correspond à la taille d’un SDWORD. Sur certains ordinateurs, ce n’est pas un problème ; sur d’autres, cela provoquera une légère pénalité de performance ; sur d’autres encore, cela entraîne une erreur d’exécution irrécupérable. Une meilleure solution consisterait à aligner chaque adresse liée sur sa limite d’alignement naturelle. En supposant qu’il s’agit de 1 pour un UCHAR, 2 pour une ÉPÉE et 4 pour un SDWORD, cela donne le résultat illustré dans l’illustration suivante, où un « X » représente un octet de mémoire utilisé et un « O » représente un octet de mémoire inutilisée.

Binding by natural alignment boundary

Bien que cette solution n’utilise pas la mémoire de l’application, elle ne rencontre aucun problème d’alignement. Malheureusement, il faut beaucoup de code pour implémenter cette solution, car chaque colonne doit être alignée individuellement en fonction de son type. Une solution plus simple consiste à aligner toutes les colonnes sur la taille de la limite d’alignement la plus grande, qui est 4 dans l’exemple illustré dans l’illustration suivante.

Binding by largest alignment boundary

Bien que cette solution laisse des trous plus grands, le code à implémenter est relativement simple et rapide. Dans la plupart des cas, cela annule la pénalité payée en mémoire inutilisée. Pour obtenir un exemple qui utilise cette méthode, consultez Utilisation de SQLBindCol.