Mon collègue affirme que nous devrions disséquer notre application C ++ (C ++, Linux) dans des bibliothèques partagées pour améliorer la modularité, la qualification et la réutilisation du code. P>
De mon point de vue, il s'agit d'un fardeau car le code que nous écrivons n'a pas besoin d'être partagé entre les applications de la même machine ni pour être chargée de manière dynamique ou déchargée et nous pouvons simplement relier une application exécutable monolithique. p>
En outre, enveloppez des classes C ++ avec des interfaces de fonction C imho le rend plus laid. P>
Je pense aussi que l'application mono-file sera beaucoup plus facile à mettre à niveau à distance sur le site d'un client. P>
Les bibliothèques dynamiques doivent-elles être utilisées lorsqu'il n'est pas nécessaire de partager du code binaire entre les applications et sans chargement de code dynamique? P>
10 Réponses :
Je dirais que je dirais que le code de division dans les bibliothèques partagées pour améliorer em> sans avoir à l'esprit immédiatement un signe d'un environnement de développement infesté à la mode. Il est préférable d'écrire du code qui peut facilement être divisé à un moment donné. P>
Mais pourquoi auriez-vous besoin d'envelopper les classes C ++ dans des interfaces de fonction C, sauf pour, peut-être, pour la création d'objets? P>
Aussi, la division dans les bibliothèques partagées ici em> sonne comme un état d'esprit interprété. Dans les langages compilés, vous essayez de ne pas reporter jusqu'à ce que vous puissiez faire au moment de la compilation. La liaison dynamique inutile est exactement le cas. P>
Les incompatibilités des compilateurs facilitent la tâche de ne pas utiliser de fonctionnalités C ++ dans des interfaces de bibliothèques partagées. Par exemple, si la disposition de la classe est implémentée différemment sur le côté des clients (un aliment différent, par exemple), le code compilé par leurs compilateurs entraînerait l'application d'erreurs sur vos structures de données. Il y avait également des problèmes de table équibles avec de vieux compilateurs.
Basilevs, c'est généralement vrai, mais pour ce que je comprends, il ne s'applique aucune manière à l'affaire.
@BavileVs: La solution consiste à proposer deux DLL. Sur la DLL C ++ qui sera utilisée par le code client sur le même compilateur et l'autre offrant une interface C au premier. Il n'est pas nécessaire de pénaliser les clients qui partagent les mêmes compilateurs en leur imposant une interface C.
@Basilevs: et pirate informatique a raison: dans l'affaire en cours, le compilateur est déjà connu et unique pour toutes les bibliothèques statiques. Je ne vois aucune raison pour que cela change devrait essayer la solution "Bibliothèque partagée". Donc, fondamentalement, aucune interface C n'est nécessaire entre les bibliothèques partagées. IMHO, cet argument "C interface C" montre que l'auteur de la question n'est pas familier avec les bibliothèques partagées.
Les bibliothèques partagées viennent avec leurs maux de tête, mais je pense que les bibliothèques partagées sont la bonne façon d'aller ici. Je dirais dans la plupart des cas, vous devriez pouvoir faire des parties de votre application modulaires et réutilisables ailleurs dans votre entreprise. De plus, en fonction de la taille de cet exécutable monolithique, il peut être plus facile de télécharger un ensemble de bibliothèques mises à jour au lieu d'un grand fichier. P>
IMO, les bibliothèques générales conduisent à un meilleur code, de code plus testable et permet de créer des projets futurs de manière plus efficace, car vous ne réinventez pas la roue. P>
En bref, je suis d'accord avec votre collègue. P>
Mais où est le point du code modulateur qui ne sera probablement jamais réutilisé? J'accepterais la modélisation mais seulement à un point où cela vaut les efforts.
IMO, je trouve que la modularisation vaut la peine d'effort dans la plupart des cas, en particulier lorsque vous parlez d'une application "monolithique". Je ne trouve pas que le temps chargé de compiler des choses dans des bibliothèques et de les utiliser dans mon code. Pourquoi les bibliothèques ne font rien de magique, je pense qu'elles aident à faire apparaître des dépendances, entraîner une meilleure vérification, une période de compilation plus rapide et un meilleur environnement. Plus tard, si le code finit par être utilisé à nouveau, quand et qui décide de le faire une liber? Le programmeur prendra-t-il le temps de le faire puis ou de copier simplement les fichiers dans son projet et compiler? Cela évite un gâchis de le faire tôt.
L'application des bibliothèques partagées garantit que les bibliothèques n'ont pas de dépendances circulaires. L'utilisation de bibliothèques partagées conduit souvent à des erreurs de liaison et de liaison plus rapides sont découvertes à une étape antérieure que s'il n'ya pas de liaison avant que la demande finale ne soit liée. Si vous souhaitez éviter d'expédier plusieurs fichiers à des clients, vous pouvez envisager de relier la demande de manière dynamique dans votre environnement de développement et de manière statique lorsque la création de constructions de version. P>
Edit: Je ne vois pas vraiment de raison pour laquelle vous devez envelopper vos classes C ++ à l'aide des interfaces C - cela se fait dans les coulisses. Sur Linux, vous pouvez utiliser des bibliothèques partagées sans aucune manipulation spéciale. Sous Windows, toutefois, vous auriez besoin de ___ DeclSpec (Exporter) et ___ DeclSpec (Import). P>
Vous pouvez, au moins sur certains systèmes, avez des bibliothèques partagées avec des symboles non résolus. Il est donc possible de créer un groupe de bibliothèques partagées de manière à être liée à une application ensemble.
Réponse courte: non. p>
Réponse plus longue: Bibliothèques dynamiques Ajoutez rien à ajouter au test, à la modularité ou à la réutilisation qui ne peut pas être effectuée aussi facilement dans une application monolithique. À propos du seul avantage que je peux penser, c'est que cela puisse forcer la création d'une API dans une équipe qui n'a pas la discipline de le faire par eux-mêmes. p>
Il n'y a rien de magique d'une bibliothèque (dynamique ou autre). Si vous avez tout le code pour créer une application, les bibliothèques assorties, vous pouvez tout aussi facilement compiler ensemble dans un seul exécutable. P>
En général, nous avons constaté que les coûts de devoir traiter avec des bibliothèques dynamiques ne valent pas la peine, à moins d'une nécessité impérieuse (bibliothèques dans plusieurs applications, qui devaient mettre à jour un certain nombre d'applications sans recompilation, permettant à l'utilisateur de ajouter des fonctions à l'application). P>
Améliorer la réutilisation Même s'il n'y en aura plus? Ne ressemble pas à un argument fort. P>
Modularité et testabilité du code ne doivent pas nécessairement dépendre de l'unité de déploiement ultime. Je m'attendrais à ce que des liens soient une décision tardive. P>
Si vraiment vous en avez une livrable et que vous n'anticitez jamais de changement à cela, cela ressemble à une surkill et à une complexité inutile de livrer en morceaux. P>
Faites une analyse de coûts / avantages simples - avez-vous vraiment besoin de modularité, de testabilité et de réutilisation? Avez-vous le temps de passer à refactoriser votre code pour obtenir ces fonctionnalités? Plus important encore, si vous faites refacteur, les avantages que vous bénéficiez de justifieront-ils le temps nécessaire pour effectuer le refactoring? P>
Sauf si vous avez des problèmes avec les tests maintenant, je vous recommande de laisser votre application tel quel. La modularisation est excellente mais Linux a sa propre version de "DLL Hell" (voir ldconfig code>), et vous avez déjà indiqué que la réutilisation n'est pas une nécessité. P>
qui n'a pas besoin de testabilité?
sur Linux (et Windows) Vous pouvez créer une bibliothèque partagée à l'aide de C ++ et ne pas avoir à le charger à l'aide des exportations de fonction C. P>
C'est-à-dire que vous construisez CLASA.CPP dans CLASSA.SO, et vous construisez Classb.cpp dans Classb (.exe) qui relie la classeA.SO. Tout ce que vous faites vraiment, c'est la division de votre application en plusieurs fichiers binaires. Cela a l'avantage de pouvoir compiler plus vite, plus facile à gérer et vous pouvez écrire des applications qui chargent uniquement le code de la bibliothèque pour les tests. P>
Tout est toujours C ++, tout ce que votre fichier .so est séparé de votre application statique liée. P>
Maintenant, si vous vouliez charger un objet différent au moment de l'exécution (c'est-à-dire que vous ne savez pas lequel se charger jusqu'à l'exécution), vous auriez besoin de créer un objet partagé avec C-Exportations, mais vous serez également charger ces fonctions manuellement; Vous ne seriez pas en mesure d'utiliser la lieur pour le faire pour vous. P>
Si vous posez la question et que la réponse n'est pas évidente, alors restez là où vous êtes. Si vous n'avez pas compris le point où la construction d'une application monolithique prend trop de temps ou si elle est trop douloureuse pour que votre groupe travaille ensemble, il n'y a pas de raison convaincante de passer aux bibliothèques. Vous pouvez créer un cadre de test qui fonctionne sur les fichiers de l'application si vous le souhaitez, vous pouvez simplement créer un autre projet utilisant les mêmes fichiers, mais joignez une API de test et construisez une bibliothèque avec celle-là. P>
À des fins d'expédition, si vous souhaitez créer des bibliothèques et expédier un grand exécutable, vous pouvez toujours les créer de manière statique. P>
Si la modularité aiderait avec le développement, c'est-à-dire que vous saurez toujours la tête avec d'autres développeurs sur des modifications de fichiers, alors les bibliothèques mai em> l'aide, mais ce n'est pas une garantie non plus. L'utilisation d'un bon design de code orienté objet aidera sans distinction. P>
et il n'y a aucune raison d'envelopper toutes les fonctions avec des interfaces appelables C-appelables nécessaires pour créer une bibliothèque, sauf si vous le souhaitez que cela soit appelable de c. P>
S'il croit que la scission de votre code dans des bibliothèques partagées améliorera la modularité, la vérification et la réutilisation du code, je suppose que cela signifie qu'il estime que vous avez des problèmes avec votre code, et que l'application d'une architecture "Bibliothèque partagée" corrigera . P>
Votre code doit avoir des interdépendances indésirables qui n'auraient pas eu lieu avec une séparation plus propre entre "code de bibliothèque" et "code à l'aide du code de bibliothèque". P>
Maintenant, cela peut également être atteint par des bibliothèques statiques. P>
Votre code pourrait être mieux testé, peut-être des tests d'unité de construction de chaque bibliothèque partagée séparée, automatisée à chaque compilation. P>
Maintenant, cela peut également être atteint par des bibliothèques statiques. P>
Votre collègue souhaite réutiliser du code qui n'est pas exposé car caché dans les sources de votre application monolithique. P>
Les points 1 et 2 peuvent encore être obtenus avec des bibliothèques statiques. Les 3 bibliothèques partagées obligatoires obligatoires. P>
Maintenant, si vous avez plus d'une profondeur de liaison de la bibliothèque (je pense à la liaison de deux bibliothèques statiques qui ont été compilées reliant les autres bibliothèques), cela peut être complexe. Sous Windows, cela conduit à une erreur à lier comme certaines fonctions (généralement les fonctions d'exécution C / C ++, lorsqu'elles sont liées de manière statique) sont référencées plus d'une fois et le compilateur ne peut pas choisir la fonction à appeler. Je ne sais pas comment cela fonctionne sur Linux, mais je suppose que cela pourrait arriver aussi. P>
Vos propres arguments sont un peu biaisés: P>
Le fardeau de la compilation et du lien vers des bibliothèques partagées, comparés à la compilation et à la liaison à des bibliothèques statiques, est inexistante. Donc, cet argument n'a pas de valeur. P>
Chargement de manière dynamique / Déchargement d'une bibliothèque partagée pourrait être un problème dans un cas d'utilisation très limité. Dans des cas normaux, le système d'exploitation chargée / décharge la bibliothèque en cas de besoin sans votre intervention, et de toute façon, vos problèmes de performance menent ailleurs. P>
Quant à l'utilisation d'une interface C-Fonction pour votre code C ++, je ne comprends pas: vous vous associez déjà des bibliothèques statiques avec une interface C ++. La liaison des bibliothèques partagées n'est pas différente. P>
Vous auriez un problème si vous aviez des compilateurs différents pour produire chaque bibliothèque de votre application, mais ce n'est pas le cas, car vous liez déjà vos bibliothèques statiquement. P>
Vous avez raison. P>
TL; Dra (trop long; a lu quand même) L'OP ne suggère pas qu'ils relient des bibliothèques statiques et sans un tel indice, il convient de supposer qu'ils produisent l'exécutable en reliant un grand nombre de fichiers d'objet. En outre, il me semble que l'OP pourrait être biaisé au point de (inconsciemment) enflure des bibliothèques statiques et partagées; J'ai du mal à croire que son collègue ne saurait pas savoir (la plupart des) avantages qu'il était après avoir pu être atteint en utilisant des bibliothèques statiques.
Premièrement, laissez-moi vous dispenser avec une hypothèse incorrecte dans votre question. Vous n'avez pas besoin d'envelopper votre C ++ avec une interface C. P>
Maintenant, passons à des cas. p>
non-problèmes: strong> p>
Avantages: strong> p>
Non ça ne le fait pas. Cela sent une question où il est possible de distinguer les bonnes et les mauvaises réponses. Et donc les gens qui écrivent de bonnes réponses méritent la récompense du représentant. Utilisez CW lorsque toutes les réponses sont égales (disons, dans un sondage ou un fil de blague)
Avoir des frontières difficiles entre les composants pour empêcher une création accidentelle ou paresseuse de dépendances a du sens. Dans votre cas, il devrait suffire de diviser l'application en bibliothèques lies statiquement liées. Vous pouvez donc conserver l'exécutable unique et avoir toujours des unités de compilation distinctes.
Il n'est pas nécessaire d'écrire des wrappers C pour rien.