Question

Au cours des mois, j'ai écrit une belle fonctionnalité assez générique que je veux construire une bibliothèque et un lien dynamique contre plutôt que d'importer en-tête de 50 impairs / fichiers source.

Le projet est maintenu dans Xcode et Dev-C ++ (je comprends que je pourrais avoir à aller ligne de commande pour faire ce que je veux) et doivent établir un lien avec OpenGL et SDL (dynamique dans le cas de SDL). Plates-formes cibles sont Windows et OS X.

Qu'est-ce que je regarde du tout?

  • Quel sera le point d'entrée de mon bibliothèque si elle a besoin d'un?
  • Qu'est-ce que je dois changer dans mon code? (Conventions d'appel?)
  • Comment puis-je le libère? Ma compréhension est que les en-têtes et compilé bibliothèque (dll, .dylib (, .framework), quoi que ce sera) doivent être disponible pour le projet - d'autant plus que la fonctionnalité de modèle ne peuvent pas être inclus dans la bibliothèque par nature.
  • Que je dois être au courant?
Était-ce utile?

La solution

Je vous recommande la construction comme une bibliothèque StatC plutôt que d'une DLL. Beaucoup des questions d'exportation C ++ fonctions et les classes disparaissent si vous faites cela, à condition que vous ne l'intention de créer un lien avec le code produit par le même compilateur vous avez construit la bibliothèque.

Construire une bibliothèque statique est très facile car il est juste une collection de fichiers .o / obj - un peu comme un fichier ZIP, mais sans compression. Il n'y a pas besoin d'exporter quoi que ce soit - il suffit d'inclure la bibliothèque dans la liste des fichiers que vos liens d'application avec. Pour accéder à des fonctions ou des classes spécifiques, il suffit d'inclure le fichier d'en-tête pertinent. Notez que vous ne pouvez pas vous débarrasser des fichiers d'en-tête -. Le modèle de compilation C ++, en particulier pour les modèles, dépend de leur

Autres conseils

Il peut être difficile d'exporter une bibliothèque de classes C ++ à partir d'une bibliothèque dynamique, mais il est possible.
Vous devez marquer chaque fonction à exporter à partir de la DLL (syntaxe dépend du compilateur). Je farfouillé pour voir si je peux trouver comment faire de Xcode. Dans VC, il est __declspec (dllexport) et CodeWarrior il est #pragma exportation sur / # export pragma off.

Ceci est tout à fait raisonnable si vous utilisez uniquement votre binaire en interne. Cependant, un problème est que les méthodes de C sont nommés différemment par différents compilateurs. Cela signifie que personne qui utilise un autre compilateur sera en mesure d'utiliser votre DLL, à moins que vous n'exportez des fonctions C.

, vous devez également vous assurer que les conventions d'appel correspondance dans la DLL et le client de la DLL. Cela signifie soit que vous devriez avoir la même default appelant le drapeau de la convention passée au compilateur tant pour la DLL ou le client, ou mieux, définir explicitement la convention d'appel de chaque fonction exportée dans la DLL, de sorte que n'importe ce que la valeur par défaut est pour le client.

Cet article explique la question du nom: http://en.wikipedia.org/wiki/Name_decoration

La norme C de ne définit pas un ABI standard, et de mauvaises nouvelles pour les gens qui essaient de construire des bibliothèques C ++. Cela signifie que vous obtenez un comportement différent de votre code compilé selon lequel les drapeaux ont été utilisés pour compiler, et qui peut conduire à des bogues dans le code mystérieux qui compile et des liens très bien.

Cela va au-delà des conventions d'appels - code C ++ peut être compilé pour appuyer ou non RTTI, la gestion des exceptions, et diverses optimisations qui peuvent affecter la la mise en page de la mémoire des instances de classe, dont le code C ++ repose sur

Alors, que pouvez-vous faire? Je construirais des bibliothèques C ++ dans mon arbre source, et assurez-vous qu'ils sont construits dans le cadre de la construction de mon projet, et que toutes les bibliothèques et le code qui lie les utiliser les mêmes drapeaux du compilateur.

Notez que mangling nom, qui était censé au moins vous empêcher de lier des fichiers objets qui ont été compilés avec différents compilateurs / drapeaux du compilateur ne fonctionne la plupart du temps, et il y a certaines choses que vous pouvez faire, en particulier avec GCC, qui se traduira par code qui lie bien et échoue à l'exécution.

Vous devez être très prudent avec le fournisseur fourni bibliothèques C ++ dynamiques (QT sur la plupart des distributions Linux, par exemple.) Je l'ai vu des exemples de bibliothèques fournies fournisseurs qui ont été compilées de façon qui ont empêché certaines choses de fonctionner correctement. Par exemple, certains Redhat Linux libère (peut-être tous) les exceptions handicapées dans l'intervalle QT, ce qui rendait impossible d'intercepter les exceptions en main () si les exceptions ont été jetés dans un rappel QT. Fun.

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