2009-02-03 20 views
10

Sooooo Sto scrivendo un interprete di script. E in fondo, voglio che alcune classi e funzioni memorizzate in una DLL, ma voglio la DLL per cercare le funzioni all'interno dei programmi che si collegano ad esso, come,Compilazione di una DLL con gcc

 program    dll 
---------------------------------------------------- 
send code to dll-----> parse code 
           | 
           v 
          code contains a function, 
          that isn't contained in the DLL 
           | 
list of functions in <------/ 
program 
     | 
     v 
corresponding function, 
user-defined in the 
program--process the 
passed argument here 
     | 
     \--------------> return value sent back 
          to the parsing function 

mi chiedevo in fondo, come faccio compilo una DLL con gcc? Bene, sto usando una porta Windows di gcc. Una volta che compilo un file .dll che contiene le mie classi e funzioni, come faccio a collegarmi ad esso con il mio programma? Come uso le classi e le funzioni nella DLL? La chiamata DLL può funzionare dal programma che si collega ad esso? Se creo un oggetto di classe {...}; nella DLL, quindi quando la DLL viene caricata dal programma, l'oggetto sarà disponibile per il programma? Grazie in anticipo, ho davvero bisogno di sapere come lavorare con le DLL in C++ prima di poter continuare con questo progetto.

"È possibile aggiungere ulteriori dettagli sul motivo per cui si desidera che la DLL chiami funzioni nel programma principale?"

Ho pensato che il diagramma lo spiegasse ... il programma che usa la DLL passa un pezzo di codice alla DLL, che analizza il codice, e se le chiamate di funzione si trovano in detto codice allora le funzioni corrispondenti all'interno della DLL sono chiamato ... ad esempio, se avessi passato "a = sqrt (100)", la funzione di parser DLL avrebbe trovato la funzione chiamata a sqrt(), e all'interno della DLL sarebbe stata una corrispondente funzione sqrt() che calcolerebbe il quadrato root dell'argomento passato ad esso, e quindi prenderebbe il valore di ritorno da quella funzione e lo metterà nella variabile a ... proprio come qualsiasi altro programma, ma se un gestore corrispondente per la funzione sqrt() non viene trovato all'interno la DLL (ci sarebbe una lista di funzioni supportate nativamente) quindi chiamerebbe una funzione simile che risiederà all'interno del programma usando la DLL per vedere se ci sono funzioni definite dall'utente con quel nome.

Quindi, diciamo che hai caricato la DLL nel programma dando al tuo programma la capacità di interpretare gli script di questo particolare linguaggio, il programma potrebbe chiamare le DLL per elaborare singole righe di codice o passare i nomi dei file degli script per elaborare ... ma se vuoi aggiungere un comando allo script adatto allo scopo del tuo programma, potresti dire di impostare un valore booleano nella DLL dicendogli che stai aggiungendo funzioni alla sua lingua e quindi creare una funzione nel tuo codice che elencerebbe le funzioni che si stanno aggiungendo (la DLL la chiamerebbe con il nome della funzione che desidera, se quella funzione è definita dall'utente all'interno del proprio codice, la funzione chiamerebbe la funzione corrispondente con l'argomento passato ad essa dalla DLL , restituisce il valore restituito della funzione definita dall'utente alla DLL e, se non esistesse, restituirebbe un codice di errore o NULL o s omething). Sto iniziando a capire che dovrò trovare un altro modo per aggirare questo per fare le chiamate di funzione vanno in un modo solo

+0

wow, non sapevo nemmeno che esistesse un porto vincente di gcc. Avrei provato a utilizzare gcc con Windows come target della piattaforma. – cbrulak

+0

Probabilmente dovresti specificare il compilatore esatto che stai utilizzando. Probabilmente la documentazione per quel compilatore ti dice come creare DLL. – SoapBox

+0

si chiama mingw, o mingw32 credo ... Cercherò di trovare la documentazione di gcc ma sono abbastanza nuovo per C e C++ quindi alcuni aspetti di esso sono difficili da capire ancora – user61721

risposta

-1

Si può sempre caricare la DLL in fase di esecuzione con load library

+0

Ok, grazie , Sto ancora avendo problemi a capire come compilarlo, e come ottenere la DLL per cercare le procedure all'interno del programma che sta chiamando, se è possibile che – user61721

8

This link spiega come farlo in un modo semplice.

In una vista a immagine grande, quando si crea una DLL, si sta creando una libreria che viene caricata in fase di esecuzione. Contiene un numero di simboli che vengono esportati. Questi simboli sono in genere riferimenti a metodi o funzioni, oltre a compilatore/linker goo.

Quando si crea normalmente una libreria statica, c'è un minimo di goo e il linker carica il codice necessario e lo ricompone nel proprio eseguibile.

In una DLL, in realtà si ottengono due prodotti finali (tre in realtà solo aspettare): una DLL e una libreria di stub. Lo stub è una libreria statica che assomiglia esattamente alla tua libreria statica, eccetto che invece di eseguire il codice, ogni stub è in genere un'istruzione di salto per una routine comune.La routine comune carica la tua DLL, ottiene l'indirizzo della routine che vuoi chiamare, quindi aggiusta l'istruzione di salto originale per andare lì così quando lo chiami di nuovo, finisci nella tua DLL.

Il terzo prodotto finale è in genere un file di intestazione che indica tutti i tipi di dati nella libreria.

Quindi i passaggi sono: crea le intestazioni e il codice, crea una DLL, crea una libreria di stub dalle intestazioni/codice/un elenco di funzioni esportate. Il codice finale collegherà la libreria stub che caricherà la DLL e risolverà la tabella di salto.

compilatore/linker goo include cose come assicurandosi che le librerie di runtime sono dove sono necessari, facendo in modo che i costruttori statici vengono eseguiti, facendo in modo che i distruttori statici sono registrati per l'esecuzione successiva, ecc, ecc, ecc

Ora come per il tuo problema principale: come posso scrivere codice estensibile in una DLL? Ci sono un certo numero di modi possibili - un modo tipico è definire una pura classe astratta (alias interface) che definisce un comportamento e lo passa in una routine di elaborazione o per creare una routine per la registrazione delle interfacce per fare il lavoro, quindi l'elaborazione la routine chiede al registrar che un oggetto gestisca un pezzo di lavoro per esso.

+0

questo è un po 'sopra la mia testa .. "Normalmente, tu" d creare questa lista a mano con un editor di testo, "come posso creare il file delle esportazioni? Cos'è una cygwin dll?Posso inserire classi in una DLL? – user61721

2

Sul dettaglio di ciò che si intende risolvere, forse si dovrebbe guardare un parser estendibile come lua invece di crearne uno proprio.

Per la tua attenzione più specifica.
Una DLL è (tipicamente?) Pensata per essere completa in sé e per sé, o sapere esplicitamente quali altre librerie utilizzare per completare se stessa.

Ciò che intendo è che non è possibile avere un metodo implicitamente fornito dall'applicazione chiamante per completare la funzionalità DLL.

Si potrebbe tuttavia rendere parte della propria API la fornitura di metodi da un'app chiamante, rendendo così la DLL completamente contenuta e il passaggio di conoscenza esplicito.

Come utilizzare le classi e le funzioni nella DLL?
Includere le intestazioni nel codice, quando il modulo (exe o un'altra DLL) è collegato, le dll vengono controllate per completezza.

Può la chiamata DLL funzioni dal programma che si collega ad esso?
Sì, ma deve essere detto su di loro in fase di esecuzione.

Se creo un oggetto di classe {...}; nella DLL, quindi quando la DLL viene caricata dal programma, l'oggetto sarà disponibile per il programma?
Sì, sarà disponibile, tuttavia è necessario conoscere alcune limitazioni. Come ad esempio nel campo della gestione della memoria è importante uno:

  • link tutti i moduli condividono la memoria con la gestione dll stessa memoria (tipicamente c runtime)
  • Assicurarsi che la memoria viene allocata e dealloccated solo nel stesso modulo.
  • allocare sullo stack

esempi!
Ecco un'idea di base per passare le funzioni alla DLL, tuttavia nel tuo caso potrebbe non essere molto utile in quanto è necessario sapere in anticipo quali altre funzioni si desidera fornire.

// parser.h 
struct functions { 
    void *fred (int); 
}; 

parse(string, functions); 

// program.cpp 
parse("a = sqrt(); fred(a);", functions); 

Quello che vi serve è un modo di registrare le funzioni (e le loro informazioni con la dll.) Il problema più grande qui è il dettaglio bit. Ma ignorando che si potrebbe fare qualcosa come wxWidgets fa con la registrazione della classe. Quando method_fred viene configurato dalla tua app, chiamerà il costruttore e registrerà la dll tramite l'uso di methodInfo. Parser può cercare metodoInfo per i metodi disponibili.

// parser.h 
class method_base { }; 
class methodInfo { 
    static void register(factory); 
    static map<string,factory> m_methods; 
} 

// program.cpp 
class method_fred : public method_base { 
    static method* factory(string args); 
    static methodInfo _methoinfo; 
} 
methodInfo method_fred::_methoinfo("fred",method_fred::factory); 
0

Sembra un lavoro per le strutture dati.

Creare una struttura contenente le parole chiave e la funzione associata a ciascuna.

struct keyword { 
    const char *keyword; 
    int (*f)(int arg); 
}; 

struct keyword keywords[max_keywords] = { 
    "db_connect", &db_connect, 
} 

quindi scrivere una funzione nella DLL che si passa l'indirizzo di questa matrice a:

plugin_register(keywords); 

Poi all'interno della DLL che può fare:

keywords[0].f = &plugin_db_connect; 

Con questo metodo, il codice per gestire le parole chiave dello script rimane nel programma principale mentre la DLL manipola le strutture dati per richiamare le proprie funzioni.

Portandolo a C++, rendere invece la struct una classe che contiene un file std :: vector o std :: map o qualsiasi parola chiave e alcune funzioni per manipolarli.

0

Winrawr, prima di andare avanti, leggere questo primo:

Any improvements on the GCC/Windows DLLs/C++ STL front?

In sostanza, si può incorrere in problemi quando si passano le stringhe STL intorno le DLL, e si può anche avere problemi con eccezioni che superano i confini della DLL, anche se non è qualcosa che ho già sperimentato (ancora).

Problemi correlati