2010-04-27 9 views
5

Problema:Errore di collegamento: xxx è già definito in *****. LIB :: Cosa è esattamente sbagliato?

Sto cercando di utilizzare una libreria denominata DCMTK che ha usato alcune altre librerie esterne (zlib, libtiff, libpng, libxml2, libiconv). Ho scaricato queste librerie esterne (* .LIB & * .h file) dallo stesso sito web. Ora, quando compilo la biblioteca DCMTK sto ricevendo errori di collegamento (793 errori) in questo modo:

Error 2 error LNK2005: __encode_pointer already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 
Error 3 error LNK2005: __decode_pointer already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 
Error 4 error LNK2005: __CrtSetCheckCount already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 
Error 5 error LNK2005: __invoke_watson already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 
Error 6 error LNK2005: __errno already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 
Error 7 error LNK2005: __configthreadlocale already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 
Error 8 error LNK2005: _exit already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir 

Documentazione:

Questo sembra essere un errore popolare per questa libreria in modo, che fanno avere una voce FAQ affrontare questo problema, che (http://forum.dcmtk.org/viewtopic.php?t=35) dice:

  • il problema è che il linker cerca di combinare diverso, versioni incompatibili della libreria di runtime Visualin un singolo binario .
  • Ciò accade quando non tutte le parti del progetto e le librerie collegate a sono generate con le stesse opzioni di generazione del codice in Visual C++.
  • Non utilizzare la soluzione/NODEFAULTLIB, poiché potrebbero verificarsi errori anomali del software . Risolvi il problema!

  • DCMTK è predefinita compilato con l'opzione "Multithreading debug" generazione di codice "Multithreading" o (la quest'ultimo per la modalità di debug).

  • sia cambiare le impostazioni del progetto di tutto il codice per utilizzare questi codice opzioni di generazione,
  • o modificare il codice di generazione per tutti i moduli DCMTK e ri-compilazione.
  • utenti MFC attenzione: DCMTK deve essere compilato con "Multithreading DLL" o "Multithreading DLL Debug" impostazioni se che si desidera collegare le librerie in un'applicazione MFC.

soluzione per lo stesso problema per gli altri:

Huge Amount of Linker Issues with Release Build Only dice:

La tua build di rilascio è cercando di collegare a qualcosa che era di debug integrata. Probabilmente hai una dipendenza interrotta da nella tua build, (o hai mancato di ricostruire qualcosa a versione a mano se il tuo progetto è normalmente costruito a pezzi).

Più tecnicamente, ti sembra di essere che collegano i progetti realizzati con diverse C Run Time library impostazioni, uno con "Multi-Threaded", l'un l'altro con "Multi-Threaded Debug".Regolare le impostazioni per tutti i progetti per utilizzare lo stesso sapore della biblioteca e la questione dovrebbe andare via

Domande:

Fino ad ora ho usato pensare che mutilazione dei nomi è il solo problema che potrebbe causare errori di collegamento se non è stato standardizzato. Proprio ora so che ci sono anche altre cose che possono causare lo stesso effetto.

  1. cosa è in su con il "Debug Mode" (Multi-Threaded debug) e "modalità di rilascio" (Multi-Threaded)? Cosa sta facendo esattamente sotto il cofano? Perché esattamente questa cosa sta causando un errore di collegamento?

  2. Mi chiedo se c'è qualcosa chiamato "Debug a thread singolo" e "Single-Threaded" che di nuovo causa la stessa cosa.

  3. La documentazione parla di "Opzioni di generazione del codice". Quali opzioni di generazione del codice? WTH sono?

  4. La documentazione in particolare ci avvisa di non utilizzare/soluzione NODEFAULTLIB. (esempio/NODEFAULTLIB: msvcrt). Perché? Come potrei causare problemi? cos'è esattamente?

  5. Spiegare l'ultimo punto della documentazione per gli utenti MFC. Perché userò MFC più avanti in questo progetto. Spiega perché dovremmo farlo? Quali problemi causerebbe se non lo facessi.
  6. Qualcosa di più che vorresti menzionare? Intendo riguardo a errori simili. Sono molto interessato a Linker & i suoi problemi. Quindi, se ci sono cose simili puoi menzionarle o alcune parole chiave almeno.

risposta

7

cosa è in su con la "Modalità Debug" (Multi-Threaded Debug) e "Release Mode" (Multi-Threaded)? Cosa sta succedendo esattamente sotto il cofano?Perché esattamente questa cosa sta causando il collegamento dell'errore ?

Il linker trascina nelle librerie per diversi motivi. Il più semplice è che una libreria sia elencata sulla riga di comando del linker o nel file di risposta del linker sulla riga di comando del linker. Ma qualsiasi file oggetto, sia esso compilato nel tuo progetto o inserito in una libreria, può anche contenere linker options includendo la richiesta di collegamento a librerie particolari. Infatti, il compilatore Visual C++ incorpora automaticamente tali opzioni di linker che corrispondono alle opzioni del progetto che usi durante la compilazione.

Al momento del collegamento, tutte le opzioni del linker da tutti i file oggetto e gli oggetti nei file di librerie statiche vengono combinate. Se viene richiesto più di un nome file della libreria CRT, il linker legge tutti e loro ricevono conflitti di denominazione, in cui il linker non sa quale utilizzare.

mi chiedo se c'è qualcosa che si chiama "single-threaded Debug" e "single-threaded", che provoca ancora una volta la stessa cosa.

C'era una volta, ma le ultime versioni di Visual C++ hanno solo librerie compatibili multi-thread.

La documentazione parla di "Opzioni di generazione codice". Quale codice Opzioni di generazione? WTH sono?

Look inside your project options.

La documentazione ci avvisa in modo specifico non utilizzare/soluzione NODEFAULTLIB. (esempio/NODEFAULTLIB: msvcrt). Perché? Come potrei causare problemi? cosa è esattamente ?

Se si utilizza/NODEFAULTLIB, tutte le impostazioni del linker memorizzati all'interno di file oggetto e gli oggetti in librerie vengono ignorati. Finirai con nessuna libreria di runtime e forse mancheresti altre librerie. Puoi aggiungerli di nuovo a mano, ma è ancora un gran casino.

Spiegare l'ultimo punto nella documentazione per gli utenti MFC. Perché ho intenzione di utilizzare MFC più avanti in questo progetto . Spiega perché dovremmo farlo? Quali problemi potrebbe causare se I no. Qualcosa in più ti piacerebbe parlare di ? Intendo per gli errori simili . Sono molto interessato a Linker & i suoi problemi. Quindi, se ci sono delle cose simili a puoi menzionarle o alcune parole chiave almeno.

applicazione MFC e la libreria MFC devono utilizzare le stesse funzioni di gestione della memoria, in modo che la memoria allocata da MFC può essere liberata dall'applicazione e viceversa. Anche le maniglie FILE e altre risorse sono condivise. Le DLL MFC sono già compilate per utilizzare il CRT in una DLL e, per poter condividere le risorse, è necessario utilizzare lo stesso CRT, il che significa utilizzare anche una DLL.

0

cosa è in su con il "Debug Mode" (Multi-Threaded debug) e "modalità di rilascio" (Multi-Threaded)? Cosa sta succedendo esattamente sotto il cofano? Perché esattamente questa cosa sta causando un errore di collegamento?

Sono versioni diverse della libreria di runtime C. È possibile collegare staticamente alla libreria di runtime in modalità debug e release. Nelle Opzioni di generazione del codice (menzionate sotto), quelle sarebbero "Debug multi-thread" e "Multi-Threaded". Le opzioni "DLL di debug multi-thread" e "DLL multi-thread" si collegano dinamicamente al runtime C. Collegando dinamicamente al runtime, dovrai anche spedire il tuo installatore configurato per installare il pacchetto ridistribuibile VC che contiene le giuste DLL di runtime per la tua versione di Visual C++.

staticamente il collegamento al runtime C è generalmente malvista, anche da parte di Microsoft:

In aggiunta a tutti i metodi descritti sopra di distribuire il Visual C++ librerie DLL, c'è una ultima opzione per la creazione dell'applicazione che non richiede il numero per distribuire le DLL.Tuttavia, questa opzione funziona solo per nativo solo il codice (non è supportato con/CLR) e lascia i vostri clienti sul serio vulnerabili a eventuali buchi di sicurezza come oltre che aggiunge un peso significativo sulla te stesso per rattoppare tutti i sistemi del cliente dovrebbe essere rilevata una vulnerabilità in qualsiasi delle librerie. Questa opzione è per il collegamento statico nelle librerie come file .lib anziché dinamicamente caricandoli come DLL. A tale scopo, mediante , utilizzare il flag/MT sulla riga di comando cl.exe (vs/MD) oppure selezionare l'opzione appropriata nelle proprietà del progetto tramite Visual Studio. È possibile che si desideri utilizzare questa opzione quando esegue il test delle versioni di debug in anteprima dell'applicazione su macchine di prova prima di si inizia a lavorare sull'installazione. [Vedi nota 3]

Tuttavia, posso pensare a nessun scenari in cui questo è in realtà il diritto cosa da fare quando si spedisce il prodotto ai clienti. Fondamentalmente, ciò che fa questo approccio è tirare il codice binario necessario dai file .LIB al momento della compilazione , facendolo parte dei file .exe o .dll. Aumenta la dimensione dell'applicazione e non è possibile aggiornare le librerie ad eccezione di ricompilando l'applicazione con nuovi .IBI e ridistribuendo nuovamente l'applicazione . Che cosa questo significa è che se non si va tocco ogni singola macchina che ha installata l'applicazione ogni volta v'è una vulnerabilità di sicurezza trovato in Visual C++ le librerie e completamente reinstallare i aggiornati binari, uscirete tua i clienti vulnerabili agli attacchi. Se invece si utilizza le DLL, ogni volta v'è una vulnerabilità di sicurezza trovato in Visual C++ le librerie, Microsoft installare l'aggiornamento centralmente nella cartella WinSxS via Windows Update e tutte le richieste di le DLL verrà reindirizzato alla versione aggiornata di . Questo rimuove tutte le difficoltà manutenzione su un fianco e anche permette all'utente di installare una piccola aggiornamento che toccherà tutte le loro applicazioni invece di sostituire ogni exe installata e DLL sul loro sistema . Per favore, non distribuire un'applicazione costruita collegando statico contro il Visual C++ librerie a meno che non si dispone di un sistema in posto per l'aggiornamento ogni macchina cliente e hanno anche un ottimo ragione per farlo. A questo punto, posso pensare che non ci siano circostanze in cui è la cosa giusta da fare per un'applicazione di spedizione.


mi chiedo se c'è qualcosa che si chiama "single-threaded Debug" e "single-threaded", che provoca ancora una volta la stessa cosa.

Nessuna cosa, vedere sopra.


documentazione parla qualcosa su "Opzioni" la generazione del codice. Quali opzioni di generazione del codice? WTH sono?

Fare clic con il pulsante destro del mouse sul progetto Visual C++ (da Visual Studio) e selezionare Proprietà. In Configurazione Proprietà-> C/C++ -> Generazione di codice


documentazione avverte specificamente noi non usare/NODEFAULTLIB soluzione. (esempio/NODEFAULTLIB: msvcrt). Perché? Come potrei causare problemi? cos'è esattamente?

Prendi il loro consiglio e non farlo.


Si prega di spiegare l'ultimo punto nella documentazione per gli utenti di MFC. Perché userò MFC più avanti in questo progetto. Spiega perché dovremmo farlo? Quali problemi causerebbe se non lo facessi.

Poiché MFC è collegato dinamicamente al runtime C, l'uso di librerie collegate staticamente al runtime C causerà gli errori del linker elencati per primi nel post.


Qualcosa di più vuoi parlare? Intendo riguardo a errori simili. Sono molto interessato a Linker & i suoi problemi. Quindi, se ci sono cose simili puoi menzionarle o alcune parole chiave almeno.

Dalla mia esperienza, collegamento sempre dinamico al runtime C. Generalmente ti risparmia un sacco di mal di testa come quello che stai vivendo in questo momento.

0

È necessario configurare le proprietà del progetto in modo che i collegamenti di compilazione di debug con il build di debug di DCMTK e i collegamenti di generazione del rilascio con la build di rilascio di DCMTK.

Quanto sopra è quello che devi fare. Di seguito sono riportate le spiegazioni di alcune altre cose casuali che hai chiesto.

Le versioni precedenti di Visual Studio utilizzavano librerie a thread singolo (versioni di debug e di rilascio) oltre a librerie multithread (versioni di rilascio e debug). Per il tuo progetto puoi fingere che le librerie a thread singolo non siano mai esistite.

Se si sperimentano metodi casuali per ingannare il linker in chiusura e lasciare che i problemi vengano rilevati dai clienti anziché da soli, è possibile che l'opzione/NODEFAULTLIB lo faccia. I creatori della libreria DCMTK ti avvisano di non farlo perché alcune altre persone hanno fatto la stessa cosa stupida in passato.

Problemi correlati