Come posso scoprire che cosa rende la mia domanda mescolare il CRT staticamente e dinamicamente collegato

StackOverflow https://stackoverflow.com/questions/1569222

Domanda

Ci scusiamo per il lungo post che segue.

Lo so che non è una buona idea di mescolare il C staticamente legato e collegato in modo dinamico e runtime C ++ fornita da Microsoft. La nostra applicazione al lavoro li mescola già purtroppo e noi abbiamo cercato di sistemare le cose. Per vari motivi (tra cui mancanza di familiarità con MSI, il fatto che usiamo NSIS, che forse non supporta MSMs bene, la mancanza di tempo e risorse) abbiamo deciso di collegare le CRT statico anziché dinamico. Io so i motivi per cui questa non è una buona idea, ma è stata la nostra scelta per il momento.


Il nostro codice è per lo più di serie C ++ completato da un bel po 'di altre librerie open-source.

La struttura della domanda è:. Vari moduli che si traducono in librerie statiche che a loro volta sono collegati tra loro per creare varie cose tra cui un eseguibile che ci sta dando problemi

In uscita si costruiscono tutte le il nostro codice con / MT. Per alcune delle librerie open-source abbiamo usato binari precompilati e alcuni di loro erano DLL precompilata con / MD che ci ha fatto mescoliamo i tempi di esecuzione. Così abbiamo ricompilato coloro noi stessi con / MT e li ha resi provocare non librerie statiche DLL. Questa conversione non è fatto per ogni libreria, quindi abbiamo ancora un collegamento con alcune DLL che utilizzano / MD.


Il risultato adesso è che in depends.exe tutta la nostra roba tranne uno eseguibile non direttamente dipendono msvcr80.dll o msvcp80.dll. Con non dipende direttamente voglio dire che msvcr80.dll non è un figlio della radice dell'albero mostrato da Depends.exe. A volte noi troviamo msvcr80.dll tirato in da una delle DLL di libreria, ma questo è alcuni livelli più profondi nella struttura.

Come faccio a sapere il motivo per cui è msvcr80.dll al primo livello per quello eseguibile fastidioso? Ciò che rende eseguibile che puntano direttamente al Msvcr80.dll?

Una ragione potrebbe essere che forse ci colleghiamo staticamente alla libreria A che collega usi / MD in modo che collega dinamicamente con il CRT. Quindi, il codice in una libreria finisce nel nostro eseguibile così i nostri legami eseguibili con msvcr80.dll. Ma come faccio a sapere che una delle biblioteche che fa?


Quello che ho provato finora:

  • caricare i file collegati staticamente .lib in depends.exe -> non funziona in quanto depends.exe si aspetta un file eseguibile o DLL non una libreria statica
  • uso Dumpbin.exe / direttive in materia di file collegati staticamente lib -> nessuno di loro ha mostrato msvcrt80.dll (mentre in debug, dove cerchiamo di usare / MDd per tutto, che hanno fatto spettacolo msvcrt80d.dll che mi fa pensare il metodo è buono e dimostra che tutte le librerie open-source collegate staticamente vengono compilati correttamente con / MT)
  • usare il VERBOSE /: LIB bandiera linker -> ha dimostrato che in effetti è tirando in msvcrt.lib che è la libreria di importazione per msvcr80.dll così siamo nei guai, ma non ha detto perché sta facendo che
  • utilizzare il VERBOSE flag / linker + in Visual Studio: Dipendenze aggiuntive LIBCMT.LIB + Ignora tutte le librerie predefinite SI + Ignora libreria specifica: msvcrt.lib in un disperato tentativo di rendere msvcrt.lib andare via o vedere chi tira è . Il risultato perplesso me:
    Searching C:\Program Files\Microsoft Visual Studio 8\VC\lib\msvcrt.lib:  
      Found "public: virtual void * __thiscall type_info::`vector deleting destructor'(unsigned int)" (??_Etype_info@@UAEPAXI@Z)  
        Referenced in libcmt.lib(typinfo.obj)  
        Loaded msvcrt.lib(ti_inst.obj)  
            msvcrt.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in libcmt.lib(typinfo.obj)  
            msvcrt.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in libcmt.lib(typinfo.obj)  
      Found "void __stdcall `eh vector destructor iterator'(void *,unsigned int,int,void (__thiscall*)(void *))" (??_M@YGXPAXIHP6EX0@Z@Z)  
        Referenced in msvcrt.lib(ti_inst.obj)
        Loaded msvcrt.lib(ehvecdtr.obj)

Per quanto ho capito, typinfo.obj in LIBCMT.LIB fa riferimento a un simbolo, cerca in msvcrt.lib e dopo che trova nel ti_inst.obj esso genera un errore che è definito due volte. Ma questo non ha senso. Se LIBCMT.LIB ha già il simbolo perché lo fa finire cercato in msvcrt.lib e portando quindi msvcr80.dll nel mio eseguibile? E più in generale, perché sarebbe la ricerca libreria statica per i simboli nella libreria di importazione dinamica? Perché il linker nemmeno guardare msvcrt.lib se ce l'ho nella biblioteca specifica Ignora?

Grazie per la vostra pazienza: -).

È stato utile?

Soluzione

ho la soluzione al mio problema. E 'stato un errore stupido sinistra dai tempi antichi, probabilmente.

msvcrt.lib è stato esplicitamente menzionato da noi nella casella Dipendenze aggiuntive :-( così, naturalmente, ha fatto la dll una dipendenza. E a causa di tutte le librerie open-source che scatola ha un sacco di testo, quindi non abbiamo notarlo. E ad essere onesti non abbiamo nemmeno pensare di guardare quella scatola con attenzione dal momento che non immaginavamo ci potrebbe essere un errore così grossolana nei nostri progetti.

Altri suggerimenti

Apri il tuo eseguibile con Depends.exe ed eseguire il profiler integrato in depends. Credo che questo registrerà il motivo per cui tutte le DLL vengono caricati, e da dove vengono caricati. Vedere l'opzione "Log chiamate di funzione LoadLibrary".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top