2010-01-13 12 views

risposta

17

collegamento in fase di caricamento è quando i simboli nella libreria, a cui fa riferimento l'eseguibile (o un'altra libreria) vengono gestiti quando il file eseguibile/libreria viene caricato in memoria dal sistema operativo.

Il collegamento in fase di esecuzione è quando si utilizza un'API fornita dal sistema operativo o tramite una libreria per caricare una DLL o un DSO quando è necessario e quindi eseguire la risoluzione dei simboli.

So di più sui DSO Linux rispetto alle DLL di Windows ma il principio dovrebbe essere lo stesso. Le librerie .NET potrebbero essere diverse.

In Linux, le architetture di plugin vengono eseguite in questo modo. Il tuo programma utilizzerà il collegamento di runtime per caricare una libreria e chiamare alcune funzioni. Allora forse lo scarico. Consente inoltre più librerie con gli stessi simboli esportati per essere caricati senza interferenze. Penso che le DLL funzioneranno più o meno allo stesso modo.

Gli eseguibili hanno "spazi vuoti" nelle tabelle dei simboli che devono essere riempiti da qualche libreria. Questi spazi vuoti vengono solitamente compilati in fase di caricamento o in fase di compilazione. È possibile annullare la necessità di "spazi vuoti" nella tabella dei simboli utilizzando il collegamento di runtime.

Un altro scenario in cui il collegamento di runtime è utile è per il debug delle librerie o la selezione da più librerie compatibili ABI/API in fase di esecuzione. Spesso ho una libreria, dico "foo" e una chiamata "foo_unstable" e ho un'app di test che commuta tra il 2 e fa qualche test.

Sotto Linux, per vedere quali librerie un link eseguibili a carico volta che si esegue il comando ldd e ottenere in uscita come ad esempio (su/bin/ls):

linux-vdso.so.1 => (0x00007fff139ff000) 
librt.so.1 => /lib64/librt.so.1 (0x0000003c4f200000) 
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003c4fa00000) 
libcap.so.2 => /lib64/libcap.so.2 (0x0000003c53a00000) 
libacl.so.1 => /lib64/libacl.so.1 (0x0000003c58e0000 

Il sistema operativo tenterà di carica le librerie (i file .so) al momento del caricamento. Potrebbe già avere la libreria in memoria.

14

Aiden Campana coperto i fondamentali, ma io aggiungerò:

carico collegamento dinamico tempo è compiuta solitamente collegando staticamente l'applicazione per un file o .lib.a che contiene il codice per stabilire automaticamente i collegamenti runtime simboli a essere trovato nei file .dll o .so all'avvio del programma. Questo di solito è per funzionalità fisse (ad esempio la libreria di runtime C, ecc.) E consente al programma di sfruttare i vantaggi delle correzioni di errori nelle librerie mantenendo le dimensioni eseguibili di piccole dimensioni (calcolando codice comune in una singola libreria).

Il collegamento di runtime viene utilizzato per funzionalità più dinamiche come il caricamento dei plugin. Come ha detto Aiden, si utilizza LoadLibrary() o l'equivalente per collegare attivamente i moduli al proprio programma in fase di esecuzione, magari interrogando una directory contenente DLL di plugin, caricando ciascuno a turno e parlando con un'API plugin nativa. In questo modo, il tuo programma può caricare moduli che non esistevano nemmeno quando la tua app è stata compilata/collegata e possono quindi crescere organicamente dopo la distribuzione.

Fondamentalmente entrambi i metodi finiscono per invocare l'API LoadLibrary(), ma utilizzando un set fisso di simboli e librerie nel primo caso e un set più dinamico in quest'ultimo.

+2

+1 per vantaggi di sviluppo/crescita. L'architettura modulare è bella. –

+2

Ulteriori informazioni per gli eseguibili .Net: utilizzano il collegamento dinamico in fase di esecuzione. Se apri le DLL .Net in "Dependency Walker", puoi vedere solo il link dinamico in fase di caricamento con MSCOREE.DLL. Maggiori informazioni relative a questo sono qui: http://stackoverflow.com/questions/9545603/is-mscorlib-dll-mscoree-dll-loaded-when-net-application-runs Se fai riferimento ma non usi una DLL e il Manca la DLL quindi la tua app non farà errori. È possibile visualizzare le DLL attualmente caricate in Debug> Windows> Moduli. –

9

È passato molto tempo da quando è stata posta la domanda. E le risposte di Aiden e Drew coprivano gran parte dell'essenza.Voglio solo aggiungere alcune cose dal punto di vista di un programmatore.

Se si utilizza il collegamento dinamico in fase di caricamento, è necessario collegarsi al file LIB. E poi nel codice, possiamo chiamare il metodo come esplicitamente come al solito. (Vedere Using Load-Time Dynamic Linking per il codice di esempio)

Se si utilizza il collegamento dinamico in fase di esecuzione, è necessario gestire autonomamente il caricamento/la liberazione della DLL e la ricerca delle funzioni. (Vedere Using Run-Time Dynamic Linking per il codice di esempio)

Per una scelta tra le 2 opzioni, controllare Determining Which Linking Method to Use.

Quindi, penso che il Load-Time Dynamic Linking sia solo un altro modo per risparmiare gli sforzi dei programmatori. Ma arriva al prezzo di una certa estensibilità. È possibile utilizzare solo la DLL corrispondente ai file LIB utilizzati come libreria di importazione.

Fondamentalmente, entrambi gli approcci di collegamento utilizzano l'API LoadLibrary() sulla piattaforma Windows.

0

Nell'esecuzione del collegamento dinamico in fase di caricamento l'eseguibile è collegato alla libreria DLL mentre nel collegamento dinamico di runtime non è stato collegato alcun eseguibile o alcuna DLL.

Il collegamento dinamico di runtime è preferibile quando le prestazioni di avvio dell'applicazione sono importanti

Problemi correlati