2009-04-24 5 views
17

Ho letto argomenti su entrambi i lati sull'opportunità di collegare la libreria di runtime C in modo statico o dinamico nei progetti di Visual Studio e non sono ancora del tutto sicuro di cosa pensare.Dovrei collegarmi al runtime di Visual Studio C in modo statico o dinamico?

Il mio progetto carica alcune librerie di terze parti (Python, HDF5, Trilinos e Microsoft MPI), ognuna delle quali deve essere costruita con la stessa libreria di runtime del mio eseguibile finale (altrimenti non possono essere collegate insieme). Quando si collega staticamente, ciascuna di queste librerie conterrà una copia del runtime C. Ho letto che questo è suscettibile di causare problemi perché l'eseguibile finale conterrà più copie del runtime, nessuno dei quali può interagire tra loro. Ma il linker non si lamenterebbe se gli stessi simboli fossero stati definiti in modo multiplo?

Vorrei evitare "DLL Hell" ma sono preoccupato per errori insidiosi che potrebbero derivare dal collegamento statico in più copie del runtime. Sto leggendo le cose sbagliate?

Inoltre, sto utilizzando Visual Studio 2005 e ho letto che il runtime di Service Pack 1 non è compatibile con le versioni precedenti. Significa che un'app creata senza SP1 non verrà eseguita su un computer con le DLL SP1, anche se hanno lo stesso nome (ad esempio msvcr80.dll)?

risposta

23

Il collegamento statico gonfierà tutti i file EXE e DLL e può causare arresti anomali (ad esempio se il codice in una DLL chiama free() con un puntatore allocato da malloc() in una DLL diversa).

È possibile ottenere il meglio da entrambi i mondi collegando in modo dinamico e distribuendo le DLL di runtime come assembly privati. Ciò significa semplicemente mettere una copia di una directory appositamente denominata contenente le DLL di runtime e i relativi manifest accanto al tuo eseguibile.

vedere la sezione "Distribuzione di Visual C++ DLL biblioteca come assembly privati" a http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx per i dettagli, ma fondamentalmente l'applicazione si presenta così:

c:\Program Files\My App\MyApp.exe 
c:\Program Files\My App\MyLibrary.dll 
c:\Program Files\My App\Microsoft.VC80.CRT\Microsoft.VC80.CRT.manifest 
c:\Program Files\My App\Microsoft.VC80.CRT\msvcr80.dll 

Quanto alla tua ultima domanda, sì, la macchina di destinazione ha bisogno del versioni corrette delle DLL di runtime per funzionare, ma distribuendole come assembly privati, lo si garantisce.

Un altro vantaggio è che gli utenti non amministratori possono installare l'app (non in Programmi, ma altrove) - non hanno bisogno dell'autorizzazione per scrivere file nell'area WinSxS.

+0

Questa è la risposta che stavo cercando. Sembra che le assemblee private siano la soluzione più sicura per il mio problema. Alcuni mi ricordano i pacchetti Mac in quanto un'app è distribuita in una struttura di directory fissa. Grazie! – user76293

+6

Ma gli assembly privati ​​non verranno riparati da Windows Update, corretto? Quindi dovrai tenere aggiornata la tua copia della libreria di runtime per conto tuo. Vedi anche http://blogs.msdn.com/larryosterman/archive/2004/04/29/123090.aspx –

+0

Non ho mai funzionato quegli assembly privati ​​se la mia cartella 'application' (My App) contiene un mix di 32-bit e applicazioni a 64 bit. Non puoi semplicemente aggiungere qualcosa come x32 o x64 al nome della cartella assembly, il che significa che puoi utilizzare solo gli assembly privati ​​se hai solo applicazioni a 32 bit o solo a 64 bit. – Patrick

0

Le librerie statiche non devono essere collegate in modo statico ad altre librerie statiche. Hai solo bisogno di collegare tutte le librerie statiche nel tuo progetto principale. In questo modo il compilatore non si lamenterà di più simboli.

+0

Per chiarire: non collego le librerie tra loro e non ottengo simboli definiti in modo multiplo quando collego il mio eseguibile principale. Ma non sono sicuro se nel mio eseguibile ci siano più copie del runtime C, che è ciò che accade quando vi collegate in modo statico (secondo la mia interpretazione di ciò che ho letto, che potrebbe essere sbagliato). – user76293

2

... Lo fanno staticamente ... i tentativi di risolvere DLL Hell non hanno funzionato bene ... basta aggiungere 200k extra all'installazione con il collegamento statico.

+0

Qualche idea sulle copie multiple del runtime? Questa è la mia vera domanda. – user76293

+0

Ci saranno più copie di un tempo di esecuzione che galleggiano comunque. Questo è ciò che la cartella WinSxS è (e questo è un tentativo di risolvere l'inferno DLL). Tuttavia, è confuso, quindi imballare il proprio runtime eviterà solo questi problemi. – CookieOfFortune

11

L'unica volta che si ottengono più copie del runtime è quando si collega staticamente una libreria a una DLL - ogni DLL ne riceverà una copia e così anche l'exe. Se sono tutte le librerie statiche e non DLL, si collegheranno tutte insieme e tutte le librerie condivideranno lo stesso runtime.

Questo è il lavoro del linker.