2012-01-27 12 views
6

Ecco il mio file di libreria Lib.c:Quali sono i passaggi esatti per la creazione e il collegamento a una DLL Win32 sulla riga di comando?

#include <stdio.h> 

int helloworld(){ 
    printf("Hello World DLL"); 
} 

Ecco il mio exe Main.c di file:

int helloworld(); 


int main(int argc, char** argv){ 
    helloworld(); 
} 

vorrei creare Lib.dll, e Main.exe, dove Lib.dll viene da Lib.c e Main.exe collegamenti contro Lib.dll.

Quali sono i passaggi specifici per raggiungere questo obiettivo?

+1

Se si desidera creare una DLL, è necessario un dllmain –

+3

@MikeKwan: ​​DllMain è [facoltativo] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs .85% 29.aspx) – tinman

+0

Ci sono così tanti tutorial là fuori su questo argomento, davvero non so perché preoccuparsi di chiederci a Google per voi. – karlphillip

risposta

16

Vedere la domanda correlata this su come creare la DLL.

Il codice della libreria così com'è non esporta alcun simbolo e il file eseguibile non importa i simboli dalla libreria. Due schemi tipici per farlo sono mostrati di seguito, ma potresti volerlo leggere prima.

Il primo metodo utilizza __declspec() per dichiarare nel codice quali funzioni (o altri elementi) vengono esportati dalla DLL e importati da altri eseguibili. Si utilizza un file di intestazione per dichiarare che i prodotti esportati e hanno una bandiera preprocessore utilizzato per controllare se i simboli sono esportazioni o importazioni:

mylib.h:

#ifndef MYLIB_H 
#define MYLIB_H 

#if defined(BUILDING_MYLIB) 
#define MYLIB_API __declspec(dllexport) __stdcall 
#else 
#define MYLIB_API __declspec(dllimport) __stdcall 
#endif 

#ifdef __cplusplus 
extern "C" { 
#endif 

int MYLIB_API helloworld(void); 

#ifdef __cplusplus 
} 
#endif 

#endif 

ho anche specificamente impostare la convenzione di chiamata per __stdcall come la maggior parte delle funzioni DLL (avrei potuto usare WINAPI invece di __stdcall se avessi incluso windows.h) e ho dichiarato le funzioni come extern "C" in modo che i loro nomi non venissero storpiati quando compilati come C++. Non è un problema di questo tipo in quanto è tutto C, ma se si dovesse costruire la DLL dal sorgente C e quindi si provasse ad usarlo da un eseguibile C++, i nomi importati sarebbero errati.

Il codice potrebbe quindi simile a questa:

mylib.c

#include "mylib.h" 
#include <stdio.h> 

int MYLIB_API helloworld(void) 
{ 
    printf("Hello World DLL"); 
    return 42; 
} 

Faresti costruire la vostra DLL utilizzando la seguente riga di comando. Oltre a creare la DLL si creerà la libreria di importazione (lib) necessaria per utilizzare la DLL da un altro eseguibile (così come il file di esportazione, ma che è necessario solo in certain circumstances):

cl /DBUILDING_MYLIB mylib.c /LD 

Il /DBUILDING_MYLIB argomento definisce il simbolo del preprocessore utilizzato per controllare se le funzioni nella DLL sono esportazioni (se è definita) o importazioni (non definite). Quindi lo definiresti quando costruisci la DLL ma non quando costruisci la tua applicazione.

Il parametro /LD indica a cl di produrre una DLL.

Il secondo metodo è utilizzare module definition files come indicato nei commenti. Puoi usare il codice che hai già ma devi anche creare il file di definizione del modulo.Al suo più semplice sembra che questo:

LIBRARY mylib 
EXPORTS 
    helloworld 

In questo caso per generare la DLL si richiede la seguente riga di comando:

cl /LD mylib.c /link /DEF:mylib.def 

È quindi possibile codificare l'applicazione in modo che ha usato l'intestazione libreria con la versione importata della funzione DLL:

main.c

/* No need to include this if you went the module definition 
* route, but you will need to add the function prototype. 
*/ 
#include "mylib.h" 

int main(void) 
{ 
    helloworld(); 
    return (0); 
} 

Che è possibile compilare con la seguente riga di comando (assumendo che la libreria di importazione dalla creazione della DLL si trovi nella stessa directory del main.c). Questo passaggio è lo stesso se si è utilizzato i file di definizione declspec o del modulo:

cl main.c /link mylib.lib 

argomenti passati dopo l'argomento /link sono passati sulla riga di comando del linker come appaiono, così come solo un nome di file è usato come input in più per collegamento nell'eseguibile. In questo caso, specifichiamo la libreria di importazione generata quando abbiamo creato la DLL.

Le righe di comando che ho mostrato qui sono praticamente il minimo necessario, ma ti permetteranno di creare una DLL e collegare un'applicazione ad esso.

Ho assunto che la convenzione di chiamata sia corretta in tutto quanto sopra e non ho sperimentato molto per vedere se ho sbagliato in qualsiasi momento.

+0

Dovresti essere più esplicito sul fatto che la creazione di .dll crea anche un .lib allo stesso tempo. –

+0

Questa risposta è buona. Se non ti piace usare l'estensione '__declspec', puoi creare un [file di definizione del modulo] [http://msdn.microsoft.com/en-us/library/28d6s79h (v = vs.100) .aspx] che specifica l'interfaccia esportata. Può dare più controllo su cosa (e come) esponete esternamente. –

+1

Probabilmente vuoi usare "extern" C "' per i simboli esportati, e forse anche '__stdcall' (o la macro' WINAPI'). –

Problemi correlati