Non-concordance détectée pour «RuntimeLibrary»

113

J'ai téléchargé et extrait Crypto ++ dans C: \ cryptopp. J'ai utilisé Visual Studio Express 2012 pour créer tous les projets à l'intérieur (comme indiqué dans le fichier readme), et tout a été créé avec succès. Ensuite, j'ai créé un projet de test dans un autre dossier et ajouté cryptolib en tant que dépendance. Après cela, j'ai ajouté le chemin d'inclusion afin de pouvoir facilement inclure tous les en-têtes. Lorsque j'ai essayé de compiler, j'ai eu une erreur concernant les symboles non résolus.

Pour remédier à cela, j'ai ajouté C:\cryptopp\Win32\Output\Debug\cryptlib.libpour lier des dépendances supplémentaires. Maintenant, j'obtiens cette erreur:

Error   1   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(cryptlib.obj)    CryptoTest
Error   2   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(iterhash.obj)    CryptoTest
Error   3   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(sha.obj) CryptoTest
Error   4   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(pch.obj) CryptoTest
Error   5   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(misc.obj)    CryptoTest
Error   6   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(queue.obj)   CryptoTest
Error   7   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(algparam.obj)    CryptoTest
Error   8   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(filters.obj) CryptoTest
Error   9   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(fips140.obj) CryptoTest
Error   10  error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(cpu.obj) CryptoTest
Error   11  error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(mqueue.obj)  CryptoTest

J'obtiens aussi:

Error   12  error LNK2005: "public: __thiscall std::_Container_base12::_Container_base12(void)" (??0_Container_base12@std@@QAE@XZ) already defined in cryptlib.lib(cryptlib.obj)    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   13  error LNK2005: "public: __thiscall std::_Container_base12::~_Container_base12(void)" (??1_Container_base12@std@@QAE@XZ) already defined in cryptlib.lib(cryptlib.obj)   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   14  error LNK2005: "public: void __thiscall std::_Container_base12::_Orphan_all(void)" (?_Orphan_all@_Container_base12@std@@QAEXXZ) already defined in cryptlib.lib(cryptlib.obj)   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   15  error LNK2005: "public: __thiscall std::locale::id::id(unsigned int)" (??0id@locale@std@@QAE@I@Z) already defined in cryptlib.lib(iterhash.obj) C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Warning 16  warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\LINK  CryptoTest
Error   17  error LNK1169: one or more multiply defined symbols found   C:\Data\Work\C++ VS\CryptoTest\Debug\CryptoTest.exe 1   1   CryptoTest

Le code que j'ai essayé de compiler était simple (j'ai obtenu ceci d'un autre site):

#include <iostream>
#include <string>
#include "sha.h"
#include "hex.h"
using namespace std;

string SHA256(string data) {
    byte const* pbData = (byte*) data.data();
    unsigned int nDataLen = data.size();
    byte abDigest[32];

    CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen);

    return string((char*)abDigest);
}

int main(void) {

    return 0;
}

Une idée de comment réparer ça? Je n'ai vraiment besoin que de SHA-256 pour le moment, rien d'autre. J'utilise Windows 7 64 bits et j'ai téléchargé VS C ++ aujourd'hui, donc ce devrait être la dernière version.

Momonga
la source
1
J'ai défini la bibliothèque d'exécution de mon projet sur le débogage multi-thread (c'était le paramètre utilisé dans crypto ++) et maintenant il se compile! :) Merci beaucoup.
Momonga
Les problèmes sont survenus beaucoup plus tôt lors de l'exécution VCUpgrade. Vous voyez des symptômes de l'échec de VCUpgrade qui vous a été signalé comme un succès .
jww

Réponses:

233

(Ceci est déjà répondu dans les commentaires, mais comme il manque une réponse réelle , j'écris ceci.)

Ce problème survient dans les versions plus récentes de Visual C ++ (les anciennes versions liaient généralement silencieusement le programme et il plantait et brûlait au moment de l'exécution.) Cela signifie que certaines des bibliothèques que vous liez avec votre programme (ou même certaines des sources fichiers à l'intérieur de votre programme lui-même) sont utilisent différentes versions du CRT (la bibliothèque C RunTime.)

Pour corriger cette erreur, vous devez aller dans votre Project Properties(et / ou celles des bibliothèques que vous utilisez,) puis dans C/C++, puis Code Generation, et vérifier la valeur de Runtime Library; cela devrait être exactement le même pour tous les fichiers et bibliothèques que vous liez ensemble. (Les règles sont un peu plus souples pour la liaison avec les DLL, mais je ne vais pas entrer dans le «pourquoi» et dans plus de détails ici.)

Il existe actuellement quatre options pour ce paramètre:

  1. Débogage multithread
  2. DLL de débogage multithread
  3. Version multithread
  4. DLL de version multithread

Votre problème particulier semble provenir de la liaison d'une bibliothèque construite avec "Débogage multithread" (c'est-à-dire CRT de débogage multithread statique) à un programme qui est en cours de construction à l'aide du paramètre " DLL de débogage multithread " (c'est-à-dire CRT de débogage multithread dynamique.) Vous devez changer ce paramètre soit dans la bibliothèque, soit dans votre programme. Pour l'instant, je suggère de changer cela dans votre programme.

Notez que puisque les projets Visual Studio utilisent différents ensembles de paramètres de projet pour les versions de débogage et de version (et les versions 32/64 bits), vous devez vous assurer que les paramètres correspondent dans toutes ces configurations de projet.

Pour (quelques) plus d'informations, vous pouvez voir celles-ci (liées à partir d'un commentaire ci-dessus):

  1. Avertissement des outils Éditeur de liens LNK4098 sur MSDN
  2. / MD, / ML, / MT, / LD (Utiliser la bibliothèque d'exécution ) sur MSDN
  3. Erreurs de construction avec VC11 Beta - le mélange de bibliothèques MTd avec des ex MDd ne parvient pas à se lier sur Bugzilla @ Mozilla

MISE À JOUR : (Ceci est en réponse à un commentaire qui demande la raison pour laquelle autant de soin doit être pris.)

Si deux morceaux de code que nous lions ensemble sont eux-mêmes liés et utilisent la bibliothèque standard, alors la bibliothèque standard doit être la même pour les deux, sauf si c'est génial attention à la manière dont nos deux morceaux de code interagissent et transmettent les données. En général, je dirais que pour presque toutes les situations, utilisez simplement la même version du runtime standard de la bibliothèque (en ce qui concerne le débogage / la publication, les threads et évidemment la version de Visual C ++, entre autres choses comme le débogage d'itérateur, etc.)

La partie la plus importante du problème est la suivante: avoir la même idée de la taille des objets de chaque côté d'un appel de fonction .

Considérez par exemple que les deux morceaux de code ci-dessus sont appelés Aet B. A est compilé avec une version de la bibliothèque standard et B contre une autre. Dans la vue de A, un objet aléatoire qu'une fonction standard lui renvoie (par exemple un bloc de mémoire ou un itérateur ou un FILEobjet ou autre) a une taille et une disposition spécifiques (rappelez-vous que la disposition de la structure est déterminée et fixée au moment de la compilation dans C / C ++.) Pour l'une de plusieurs raisons, l'idée de B de la taille / disposition des mêmes objets est différente (cela peut être dû à des informations de débogage supplémentaires, à l'évolution naturelle des structures de données au fil du temps, etc.)

Maintenant, si A appelle la bibliothèque standard et récupère un objet, puis passe cet objet à B, et que B touche cet objet de quelque façon que ce soit, il y a de fortes chances que B gâche cet objet (par exemple, écrire le mauvais champ, ou dépasser la fin de celui-ci, etc.)

Ce qui précède n'est pas le seul type de problèmes qui peuvent survenir. Les objets globaux ou statiques internes de la bibliothèque standard peuvent également causer des problèmes. Et il existe également des catégories de problèmes plus obscures.

Tout cela devient plus étrange dans certains aspects lors de l'utilisation de DLL (bibliothèque d'exécution dynamique) au lieu de libs (bibliothèque d'exécution statique.)

Cette situation peut s'appliquer à n'importe quelle bibliothèque utilisée par deux morceaux de code qui fonctionnent ensemble, mais la bibliothèque standard est utilisée par la plupart des programmes (sinon presque tous), ce qui augmente les risques de conflit.

Ce que j'ai décrit est évidemment une version édulcorée et simplifiée du désordre réel qui vous attend si vous mélangez des versions de bibliothèques. J'espère que cela vous donne une idée de pourquoi vous ne devriez pas le faire!

yzt
la source
Je suis un peu confus. L' erreur d'OP est LNK2038 . Comme cela ne se produit pas avec toutes les bibliothèques, je soupçonne que Crypto ++ manipule certains paramètres CRT qui rendent impossible le mélange de saveurs CRT - il ne s'agit généralement que d'un avertissement (LNK4098) et vous pouvez être en sécurité si vous savez ce que vous faites (non recommandé, mais possible avec des limitations, voir par exemple stackoverflow.com/a/19944935/948581 ). Je ne sais pas pourquoi Crypto ++ est affecté de cette manière, cependant.
1
@Tibo: ce ne sont pas des bibliothèques d'importation pour les DLL; Je crois que Crypto ++ est en fait lié statiquement au programme ici. Cela signifie que toute discordance dans la bibliothèque standard liée à un module contre un autre (probablement) viole la "règle d'une définition". Ce qui est mauvais. Ce n'était pas une erreur auparavant, car l'éditeur de liens n'était même pas capable de le détecter (les noms de fonction / type étaient les mêmes, mais leurs corps et définitions différaient considérablement) jusqu'à VC10 lorsque l'éditeur de liens / bibliothécaire a commencé à "baliser" les modules il a produit avec des informations supplémentaires sur la configuration de la construction ...
yzt
@Tibo: ... (suite du commentaire précédent) Par exemple, regardez le premier bloc d'erreurs signalé par l'OP. Ici , " RuntimeLibrary " est une balise à la fois sur la bibliothèque Crypto ++ et le fichier objet pour le programme de l'OP, et sa valeur est " MDd_DynamicDebug " pour l'un d'entre eux et " MTd_StaticDebug " pour l'autre. De cette façon, l'éditeur de liens qui tente de lier deux fichiers objets ensemble peut détecter et signaler une toute nouvelle classe d'erreurs, étant donné que les éditeurs de liens qui ont produit ces fichiers objets les ont étiquetés avec toutes les informations pertinentes, en particulier tous les paramètres susceptibles de violer l'ODR.
yzt
Bien que je sois tout à fait d'accord avec vous, il y a encore une zone de mystère ici. En ce qui concerne le problème de l'OP, je suppose qu'il inclut "dll.h" de Crypto ++, puis essaie de se lier à la bibliothèque statique au lieu de la bibliothèque d'importation de la DLL. Mais j'ai vu exactement les mêmes erreurs sur un ordinateur, pas sur un autre (VS2013 ultime sp4 -> erreur, communauté VS2013 sp5 -> ok) ...
1
@yzt J'ai trouvé une solution. Au lieu d'utiliser / ZW swicth, Windows fournit un moyen d'utiliser l'API WinRT via COM en utilisant un wrapper appelé WRL. C'est juste que ne pas utiliser / ZW rend le codage peu difficile car il cache les détails de l'implémentation COM, mais il est possible d'utiliser WinRT sans / ZW.
Sahil Singh
3

J'ai téléchargé et extrait Crypto ++ dans C: \ cryptopp. J'ai utilisé Visual Studio Express 2012 pour créer tous les projets à l'intérieur (comme indiqué dans le fichier readme), et tout a été créé avec succès. Ensuite, j'ai créé un projet de test dans un autre dossier et ajouté cryptolib en tant que dépendance.

La conversion n'a probablement pas réussi. La seule chose qui a réussi a été l'exécution de VCUpgrade. La conversion proprement dite a échoué, mais vous ne le savez pas tant que vous ne rencontrez pas les erreurs que vous voyez. Pour certains des détails, voir Visual Studio sur le wiki du Crypto.


Une idée de comment réparer ça?

Pour résoudre vos problèmes, vous devez télécharger vs2010.zipsi vous voulez une liaison d'exécution statique C / C ++ ( /MTou /MTd), ou vs2010-dynamic.zipsi vous voulez une liaison d'exécution C / C ++ dynamique ( /MTou /MTd). Les deux corrigent les échecs latents et silencieux produits par VCUpgrade.


vs2010.zip, vs2010-dynamic.zipet vs2005-dynamic.zipsont construits à partir des dernières sources GitHub . Au moment de la rédaction de cet article (1 juin 2016), c'est effectivement pré-Crypto ++ 5.6.4. Si vous utilisez les fichiers ZIP avec un Crypto ++ de bas niveau, comme 5.6.2 ou 5.6.3, vous rencontrerez des problèmes mineurs.

Je suis conscient de deux problèmes mineurs. Le premier est un changement de nom de bench.cpptobench1.cpp . Son erreur est soit:

  • C1083: Cannot open source file: 'bench1.cpp': No such file or directory
  • LNK2001: unresolved external symbol "void __cdecl OutputResultOperations(char const *,char const *,bool,unsigned long,double)" (?OutputResultOperations@@YAXPBD0_NKN@Z)

Le correctif consiste soit (1) à l'ouvrir cryptest.vcxprojdans le bloc-notes, à le trouver bench1.cpp, puis à le renommer bench.cpp. Ou (2) renommer bench.cppsur bench1.cppsur le système de fichiers. Veuillez ne pas supprimer ce fichier.

Le deuxième problème est un peu plus délicat car c'est une cible en mouvement. Les versions de niveau inférieur, telles que 5.6.2 ou 5.6.3, ne disposent pas des dernières classes disponibles dans GitHub . Les fichiers de classe manquants incluent HKDF (5.6.3), RDRAND (5.6.3), RDSEED (5.6.3), ChaCha (5.6.4), BLAKE2 (5.6.4), Poly1305 (5.6.4), etc.

Le correctif consiste à supprimer les fichiers source manquants des fichiers de projet Visual Studio, car ils n'existent pas pour les versions de bas niveau.

Une autre option consiste à ajouter les fichiers de classe manquants à partir des dernières sources, mais il pourrait y avoir des complications. Par exemple, la plupart des sources dépendent subtilement des dernières config.h, cpu.het cpu.cpp. La "subtilité" est que vous ne réaliserez pas que vous obtenez une classe sous-performante.

Un exemple de classe sous-performante est BLAKE2. config.hajoute la détection de temps de compilation ARM-32 et ARM-64. cpu.het cpu.cppajoute la détection d'instruction ARM d'exécution, qui dépend de la détection de temps de compilation. Si vous ajoutez BLAKE2 sans les autres fichiers, aucune détection ne se produit et vous obtenez une implémentation C / C ++ directe. Vous ne réaliserez probablement pas que vous manquez l'opportunité NEON, qui tourne autour de 9 à 12 cycles par octet contre 40 cycles par octet environ pour le C / C ++ vanille.

jww
la source
J'ai suivi les instructions du wiki cryptopp, téléchargé vs2010-dynamic.zip et collé son contenu sur le code cryptopp563. Construit et certains fichiers source sont manquants. Pas de problème, le wiki dit que le zip est pour le dernier projet sur github, et supprimez simplement tous les fichiers manquants. Supprimé. Maintenant, le projet ne se construit tout simplement pas: 4 erreurs de lien, un exemple: erreur LNK2001: symbole externe non résolu "void __cdecl OutputResultOperations (char const *, char const *, bool, unsigned long, double)" (? OutputResultOperations @@ YAXPBD0_NKN @ Z)
Yaniv
Il s'est avéré qu'il y avait un bench.cpp qui manquait dans le projet. Mais même après cela, il n'a pas été compilé jusqu'à ce que j'applique ce correctif à fiptest.cpp github.com/weidai11/cryptopp/pull/151/files?diff=split Je souhaite qu'ils mettent un peu d'ordre dans ce domaine, comme ajouter les fichiers zip du projet dans git ou quelque chose. Et oui, j'ai oublié de dire que mon compilateur est la mise à jour 2 de VS2015. En bout de ligne, suivez les conseils que j'ai écrits et cela fonctionne.
Yaniv
@Yaniv - Pour le premier commentaire, que recommandez-vous pour que les autres utilisateurs ne rencontrent pas de problèmes? Pour le deuxième commentaire, nous prévoyons de prendre le patch une fois que nous l'aurons entièrement testé. Pouvons-nous faire quelque chose en attendant? (J'ai ajouté des informations supplémentaires à cette réponse, mais je veux m'assurer que les utilisateurs n'ont pas de problème).
jww
Tout d'abord, merci beaucoup d'avoir fait cela. Crypto ++ est vraiment génial. En ce qui concerne les problèmes de construction, essayez de garder les fichiers sln et projet de Windows compatibles avec les derniers fichiers du projet, et comme ceux-ci changent bien sûr, ces fenêtres de construction devraient être en quelque sorte liées à la base de code, et peut-être même être dans l'arborescence des sources. Si c'est trop, assurez-vous au moins que le fichier zip avec l'environnement de construction de Visual Studio est compatible avec la version officielle stable actuelle.
Yaniv le
En ce qui concerne le correctif pour fiptest.cpp - il semble être quelque chose de différent à propos de VS2015, donc je suppose que quiconque souhaite utiliser VS2015 doit appliquer ce correctif. C'est juste un autre cas dans un bloc #ifdef qui semble définir le bon rappel de débogage pour VS2015, et il est vraiment facile de patcher manuellement.
Yaniv le
3

J'ai eu ce problème avec une incompatibilité dans ITERATOR_DEBUG_LEVEL. Comme un problème du dimanche soir après tout semblait correct et bon, j'ai été mis dehors pendant un certain temps. En travaillant dans l'IDE de VS2017 (Explorateur de solutions), j'avais récemment ajouté / copié une référence de fichier source à mon projet (ctrl-glisser) à partir d'un autre projet. En regardant dans les propriétés -> C / C ++ / Preprocessor - au niveau du fichier source, pas au niveau du projet - j'ai remarqué que dans une configuration Release, _DEBUG était spécifié au lieu de NDEBUG pour ce fichier source. C'était tout le changement nécessaire pour se débarrasser du problème.

Jan
la source
1

Le problème peut être résolu en ajoutant CRT de msvcrtd.lib dans la bibliothèque de l'éditeur de liens. Parce que cryptlib.lib utilisait la version CRT de debug.

abhijithkp
la source