2011-01-26 13 views
5

Sto cercando di implementare un'architettura plug-in nella nostra attuale applicazione (Unix, C++) e ho esaminato le opzioni (in attesa di approvazione) all'interno delle librerie Boost.Opzioni plug-in boost

Modifica: sto cercando di aggiungere in modo dinamico le classi in fase di esecuzione.

Boost.Plugin

Boost.Reflection

Boost.Extension

Mi chiedevo che cosa tutti quanti esperienza/opinione su queste e altre implementazioni.

+1

Hai pubblicato le tue soluzioni proposte per un problema che non hai indicato. Quali sono i tuoi requisiti? –

risposta

4

Eh. Abbiamo appena utilizzato dlopen e dlsym insieme con un paio di extern "C" static funzioni che deve essere definito nella DLL

extern "C" static plugin* create(arg_pack*); 
extern "C" static errno_t destroy(plugin*); 

Dai un'occhiata plug-manager per i file ".so" ".dll" o e caricarli in un
map<string, pair< plugin*(*)(arg_pack*), errno_t(*)(plugin*)> >

è quindi possibile occhiata un plugin in base al nome (la stringa sopra) e ottenere è 'costruttore' o 'distruttore'

vedi anche: gmodule

+0

Controllo compatibilità ABI/API? –

+0

@Vlad ABI -> 'extern" C "' garantisce un manichino c-style. API -> 'dlsym' per caricare tutte le funzioni rilevanti dalla libreria. Se ne mancano alcuni, non è un plugin e devi scartare i puntatori di funzione e 'dlclose' la libreria. – KitsuneYMG

+1

extern "C" garantisce maneggevolezza, ma immagina che la firma sia cambiata, o qualsiasi altra cosa che l'interfaccia fornisce sia cambiata, e il plug-in si aspetta qualcosa di diverso, la migliore scommessa sarebbe quella di andare in crash, ma le conseguenze potrebbero essere molto drammatiche (cioè i prezzi cattivi provenienti dal trading sistema, che fa fallire un'azienda in un paio di secondi). Ci dovrebbe essere una serie di controlli decenti che assicurino che qualsiasi contratto previsto sia soddisfatto. Fondamentalmente dovrebbe essere l'obiettivo principale dei framework di plugin, non solo il wrapping di dlopen ... –

1

Non è possibile caricare le classi in fase di esecuzione poiché il C++ è un linguaggio compilato e le classi non esistono in fase di esecuzione. Oggetti (istanze di classi).

Quello che puoi fare è caricare le librerie condivise in fase di esecuzione e farle creare oggetti di una determinata interfaccia.

L'implementazione di plug-in minima definisce l'interfaccia del plug-in e l'interfaccia della funzione di fabbrica che sta per creare oggetti con tale interfaccia. Caricherai la libreria condivisa in fase di esecuzione, troverai la funzione di fabbrica con un certo nome e chiami la funzione di fabbrica per creare un oggetto. Quindi si utilizza quell'oggetto attraverso l'interfaccia:

// plugin.h start 
#include <memory> 

struct PlugIn // interface 
{ 
    virtual ~PlugIn() = 0; 
    virtual void doSomething() = 0; 
}; 

extern "C" { 

typedef std::auto_ptr<PlugIn> PlugInFactoryFn(); 

// A plugin .so must export this one factory function. 
std::auto_ptr<PlugIn> createPlugIn(); 

} 
// plugin.h end 

// somewhere in you application 
#include "plugin.h" 
#include <assert.h> 
#include <dlfcn.h> 

std::auto_ptr<PlugIn> loadPlugIn(char const* filename) 
{ 
    void* so = dlopen(filename, RTLD_NOW | RTLD_LOCAL); 
    assert(so); 
    void* factory_function = dlsym(so, "createPlugIn"); 
    assert(factory_function); 
    return reinterpret_cast<PlugInFactoryFn*>(factory_function)(); 
} 

int main() 
{ 
    std::auto_ptr<PlugIn> a(loadPlugIn("a.so")); 
    std::auto_ptr<PlugIn> b(loadPlugIn("b.so")); 
    a->doSomething(); 
    b->doSomething(); 
} 
+0

Ora, questo non funzionerà su piattaforme non POSIX, potrebbero esserci problemi di heap quando l'oggetto viene allocato sull'heap del plugin e cancellato nelle applicazioni principali. Per non parlare della compatibilità API/ABI ... –

+0

@Vlad: stiamo parlando di Unix qui. –

+0

@Maxim: Tuttavia, devi assicurarti che plugin e host siano compatibili con ABI (ad esempio compilatore uguale o compatibile, ecc.), Più compatibile con API. Questo è il motivo per cui hai bisogno di alcune cose di livello superiore come Boost, e usare il cowboy dlopen è .. sai. –

Problemi correlati