Erreurs lors de la liaison à protobuf 3 sur MS Visual C
Rencontrés sur Visual Studio 2013, mais c'est reproductible avec n'importe quelle version.
J'ai cloné le protocole de la mémoire tampon de bibliothèque à partir de github, couru CMake-gui (j'ai tout laissé par défaut, donc c'est la version statique), seulement construit libprotobuf (autre projet a échoué pour une raison quelconque, cmd.exe erreur, pourrait avoir quelque chose à voir avec les tests, mais libprotobuf construit fine).
Mon projet utilise des en-têtes généré avec le .proto fichier trouvé sur le mapbox vecteur de tuiles spec github.
Quand j'ai le lien, j'ai d'abord avoir cette erreur
Error 1 error C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' s:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility
J'ai essayé de le désactiver avec -D_SCL_SECURE_NO_WARNINGS
supplémentaires dans les arguments de ligne de commande, mais j'ai d'autres erreurs:
Error 1 error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in main.obj S:\eiogit3\misc-projs\mapload\mapload\libprotobufd.lib(common.obj)
libprotobuf
version statique (.lib) en utilisant CMake, et maintenant vous essayez de lien dans votre VStudio application?Oui, je l'ai construit avec MSVC 2013, et je suis maintenant en le reliant à mon projet, également à l'aide de MSVC 2013
ici est le fichier de projet
OriginalL'auteur jokoon | 2016-01-31
Vous devez vous connecter pour publier un commentaire.
C'est un décalage de la façon dont le VStudio C (et C++) de la Bibliothèque d'Exécution (VCRTLib - vérifier [AINSI,]: Comment contourner Windows Universal CRT en-têtes de dépendance sur vcruntime.h (@CristiFati réponse)) est utilisé par votre projet et par libprotobuf projet. Permettez-moi de détail:
Disons qu'il y a quelques C code. Le but de ce code est à exécuter. Que peuvent être obtenus:
Vous pouvez vérifier [AINSI,]: Error LNK2005 dans le CLR Windows Form (@CristiFati réponse) pour les détails de la façon dont C code arrive à être transformé dans le format exécutable. Aussi Google est plein d'articles sur les différences entre la statique et la dynamique des bibliothèques, quand utiliser l'un ou l'autre, un exemple peut être trouvé sur [AINSI,]: Quand utiliser la dynamique vs statique bibliothèques.
Comme vous l'avez deviné, le CRT ou bibliothèque runtime C (qui contient le système sous-jacent qui fait C code en mesure d'exécuter un exemple sont des fonctions de gestion de mémoire: malloc, gratuit) ne fait pas exception - c'est l'équivalent de Ux's de la libc.un (statique ou archive) vs de la libc.donc (dynamique ou de l'objet partagé) - mais dans VStudio c'est un peu plus compliqué:
Notes:
Maintenant, VCRTLib parties, ne sont pas inclus dans le projet comme n'importe quel autre lib (Propriétés du Projet -> Linker -> Input -> Dépendances Supplémentaires), mais parce que leur nature (statique ou dynamique) est requis au moment de la compilation, ils sont configurés à partir de: [MME Docs]: /MD /MT /LD (Utilisation de la Bibliothèque Run-Time), où il y a 4 choix disponibles:
Évidemment, ceux qui contiennent "Debug" sont lors de la construction de Debug de configuration, tandis que les autres pour Libération; le point essentiel est que ceux qui ont DLL sont à l'aide de la dynamique version d'exécution, tandis que les autres le statique version.
De retour à votre erreur: l'éditeur de liens se plaint que principal.obj (partie de votre projet) a MDd_DynamicDebug (liaison à l'encontre de la dynamique de débogage version), tandis que commun.obj (partie de libprotobuf projet) a MTd_StaticDebug (liaison à l'encontre de la statique de débogage version), de sorte que vous lier avec 2 moteurs d'exécution dans le même exécutable (ou .dll) - qui n'est pas possible.
Afin de résoudre ce problème, vous devez vous assurer que libprotobuf et votre projet principal ont la même valeur pour VCRTLib.
Bien sûr, il est plus simple de changer votre projet principal paramètre pour correspondre à libprotobuf'un, mais il est recommandé d'utiliser la dynamique de la version du moteur d'exécution (les choses peuvent déraper dans les grands projets qui ont .dlls impliqués), même si cela nécessite de recompiler libprotobuf (ainsi, si la modification de cette option génère des erreurs qui font libprotobuf très dur à construire, et que votre projet va rester de cette simple, vous pouvez utiliser la statique VCRTLib).
Note: ne Pas confondre VCRTLib type (statique /dynamique) avec le chemin libprotobuf est en cours de construction (statique à ce point, mais je suis sûr qu'il peut être construit comme dynamique de trop).
@EDIT0:
L'ajout de quelques informations supplémentaires sur la note ci-dessus, comme certains commentaires l'a demandé, et il pourrait être utile à d'autres utilisateurs.
Il y a 2 aspects à propos d'une bibliothèque (y compris libprotobuf), qui sont totalement indépendants:
Donc, il y a 4 parfaitement valide combinaisons:
Pour libprotobuf, chacun des aspects est contrôlé par un booléen cmake option:
Les 2 indicateurs peuvent être définis soit par:
-Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF
)Le au-dessus de 4 combinaisons sont donc possible (au moins dans v3.5), mais #2. est désactivé par défaut (en précisant
-Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_MSVC_STATIC_RUNTIME=ON
va construire un .dll qui vont se lier à la dynamique VCRTLib), afin d'éviter d'éventuels problèmes d'exécution, et nécessite une intervention manuelle.Pour plus de détails concernant les instructions de compilation (via cmake), vérifier: [GitHub]: protocolbuffers/protobuf - (master) protobuf/cmake/README.md.
1: Le .lib fichier est créé uniquement si la bibliothèque exportations symboles, que ça ne ferait pas de sens contraire (il n'est pas nécessaire au moment de la liaison, et la .dll sera créé, mais à peu près inutilisable)
2: Pour les nouveaux VStudio versions (en commençant par 2015), le msvcr(t) partie a été remplacé par vcruntime (ou, au moins, c'est le point d'entrée, comme il a été divisé en petites parties logiques)
Merci, c'est maintenant construit (avec l'-D_SCL_SECURE_NO_WARNINGS en ligne de commande). Je connaissais déjà la différence entre statique et dynamique, mais je n'avais aucune idée sur ce que la bibliothèque d'exécution de réglage. Et effectivement, les google protobuf doc indique qu'il est conseillé d'utiliser la version statique, pas la version dynamique: github.com/google/protobuf/tree/master/...
Heureux d'entendre cela fonctionne. Je viens de lire les commentaires sur le lien que vous avez fourni. Maintenant en ce qui concerne votre question précédente, si c'est sur le modèle de l'exportation à la fin, alors je ne le pense pas.
Question: puis-je construire une bibliothèque statique qui utilise la dynamique de l'exécution et dans l'autre sens?
Oui. Par défaut, le libprotobuf est construit dicte la manière de VCRTLib est utilisé. Les types de builds sont contrôlées par les 2 drapeaux. Voici comment j'ai construit le statique libprotobuf version dynamique à l'aide de VCRTLib
-Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF
. Je dois ajouter ce morceau de l'info dans la réponse.OriginalL'auteur CristiFati