Quello che stai cercando di fare è creare un'applicazione estensibile : una che abbia funzionalità collegabili, magari con valori predefiniti sensibili.
Idealmente, avresti un framework come Spring per consentire la funzionalità di collegamento: tuttavia, con C ++, questo è un po 'più di lavoro che digitando un codice XML.
Il modo generale per ottenere questo risultato in C ++ è attraverso librerie dinamiche che sovrascrivono le funzionalità nell'applicazione di base.
Ad esempio, forse hai un algoritmo per i widget frobnict. Fornisci un'interfaccia Frobnicator
con metodi% virtual
che devono essere implementati. La tua applicazione fornisce un DefaultFrobnicator
che ha un'implementazione tipica. Durante l'avvio, la logica di inizializzazione indica al FrobnicatorFactory
che si desidera utilizzare DefaultFrobnicator
. Ora, ogni volta che vuoi modificare i widget, chiedi in fabbrica il frobnicator e restituisce l'istanza predefinita.
Ma aspetta! uno dei tuoi clienti desidera un'implementazione diversa di Frobnicator
. Implementano una classe che eredita Frobnicator
, fornendo la loro implementazione personalizzata. La loro logica di inizializzazione della DLL dice a FrobnicatorFactory
di utilizzare la propria implementazione. Ora il tuo codice a cui il cliente non ha accesso chiamerà nel codice cliente e il cliente non ha bisogno di accedere alla tua fonte completa: solo le parti relative ai widget di ottimizzazione.
Il pezzo finale è che durante l'avvio, l'applicazione eseguirà la propria inizializzazione, quindi caricherà librerie dinamiche arbitrarie in posizioni predefinite.
I dettagli su un punto di ingresso di una libreria dinamica e il suo funzionamento sono specifici della piattaforma. Su Windows, c'è un DllMain , mentre Linux ha diversi meccanismi . In alternativa, potresti avere un oggetto globale statico nella libreria che esegue la logica di inizializzazione: questo è garantito per l'esecuzione quando la libreria viene caricata indipendentemente dalla piattaforma.
class Frobnicator {
public:
virtual void frobnicate(Widget&) const = 0;
};
class FrobnicatorFactory {
public:
static void setFrobnicator(Frobnicator) { .. }
static Frobnicator& getFrobnicator() { ... }
};
// Some code...
Widget w(...);
FrobnicatorFactory::getFrobnicator().frobnicate(w);
// Application init
FrobnicatorFactory::setFrobnicator(DefaultFrobnicator());
// Library init, define once.
class DllInitializer {
public:
DllInitializer() {
FrobnicatorFactory::setFrobnicator(CustomerFrobnicator());
}
} x; // Note the creation here
Si noti che questa è una panoramica di base su come i funzionano in C ++. Questo è essenzialmente ciò che stai cercando di fare: esporre un meccanismo di plugin ai tuoi clienti senza fornire un codice sorgente completo.
Nota inoltre che i tuoi clienti dovranno usare lo stesso compilatore a causa del nome mangling.