Gestion des TCHAR dans les fichiers d'en-tête pour les bibliothèques avec différents jeux de caractères

StackOverflow https://stackoverflow.com/questions/813898

  •  03-07-2019
  •  | 
  •  

Question

J'ai un projet qui utilise deux bibliothèques tierces, qui utilisent toutes deux des TCHAR dans leurs fichiers d'en-tête. Malheureusement, une bibliothèque est considérée comme multi-octets (appelez-la bibliothèque a) et l'autre est compilée comme Unicode (appelez-la bibliothèque b).

Si j'ai bien compris, TCHAR est remplacé par le précompilateur avec soit wchar, soit char, en fonction des options de construction. Ainsi, lorsque la bibliothèque a été compilée, toute méthode prenant un paramètre de type TCHAR était configurée pour attendre un paramètre de type char, et les méthodes de la bibliothèque b étaient définies pour attendre un paramètre de type wchar.

Malheureusement, mon application consommatrice doit également choisir un jeu de caractères. Si je choisis Unicode, le fichier d'en-tête que j'ai inclus pour la bibliothèque a m'indique que la méthode veut un wchar, car lorsque je compile les TCHAR dans l'en-tête, ils sont interprétés comme des wchars. Ceci inclut les TCHARS définis à l'intérieur des structures. En pratique, j’ai confirmé ce comportement. Lorsque j’alloue et passe un tampon TCHAR, je récupère des ordures car il remplit mon tampon wchar avec des données multi-octets.

Mes questions sont les suivantes: existe-t-il un moyen propre de consommer ces deux bibliothèques dans la même application? Est-ce que je fais peut-être quelque chose de mal avec la façon dont j'utilise ces bibliothèques?

Était-ce utile?

La solution

En supposant que vous n'utilisiez pas trop de classes / fonctions dans l'une ou l'autre de ces bibliothèques, j'aimerais envelopper complètement l'une des bibliothèques. Supposons que si vous avez décidé d'utiliser mbc dans votre application et que vous enveloppiez la bibliothèque b (unicode), votre fichier d'en-tête d'encapsuleur peut utiliser wchar_t au lieu de TCHAR afin que #define n'affecte pas votre interface. Dans le fichier cpp de votre wrapper où vous # incluez les en-têtes de la bibliothèque b, vous # définissez TCHAR pour faire correspondre la bibliothèque b. Aucun code autre que votre wrapper ne devrait être autorisé à voir la bibliothèque b.

Si vous utilisez plusieurs classes / fonctions dans ces deux bibliothèques, la maintenance du code d'encapsulation deviendra rapidement un problème en soi.

Autres conseils

As Shing Yip suggéré, mieux vaut envelopper la différence dans une API de votre choix. Cela rend votre code source indépendant de celui-ci.

L'API d'encapsulation doit ensuite convertir les caractères de votre encodage en ceux de la bibliothèque. Sous Windows, vous disposez de fonctions appelées WideCharToMultiByte et similaires.

Je pense que votre meilleure option est de choisir soit la bibliothèque a ou la bibliothèque b (nous dirons bibliothèque a pour cet exemple) comme manière de le faire. Et ensuite, lorsque vous incluez les fichiers d'en-tête de la bibliothèque b, assurez-vous que vous # définissez / # undef quelle que soit la bibliothèque avec laquelle b a été compilée. Ensuite, vous devez vous assurer de convertir entre bibliothèque a et bibliothèque b chaque fois qu’elles utilisent les mêmes données.

Ce serait vraiment mieux si vous pouviez les compiler de la même manière. Sinon, ça va être très sale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top