Secondo me dovresti semplicemente progettare un'API appropriata per i tuoi client da chiamare mentre compilano i plugin sotto forma di un dylib che viene caricato e richiamato dalla tua applicazione.
È necessario dedicare più tempo in anticipo alla progettazione dell'API / SDK, ma puoi utilizzarlo tu stesso per creare la tua applicazione, fondamentalmente facendo il bootstrap e creando il tuo software con la stessa API e SDK che i tuoi clienti usano per creare plugin per esso . Fornisci ai tuoi clienti intestazioni che indicano le interfacce che possono utilizzare (es: tabelle dei puntatori di funzione) e passa loro un puntatore per accedere a queste interfacce quando il loro plugin viene caricato e viene invocata una funzione del punto di ingresso esportata dal proprio plug-in. Solo i file di intestazione per le interfacce pubbliche sono esposti ai tuoi clienti. Il resto rimane nascosto. Esempio semplicistico:
#ifndef SDK_H
#define SDK_H
// Central interface for your software development kit.
struct Sdk
{
// A function available for your customers to call in their plugins.
void (*do_something)(int x);
};
#endif
// Inside the plugin code, compiled separately away from your
// application with no access to its source code, only the
// header files for the SDK.
#include <sdk.h>
// This exported function inside the plugin gets loaded and called
// by your application when it loads this plugin, passing it a pointer
// to the SDK interface required to invoke all the functionality
// publicly available for plugins to call.
EXPORT void my_plugin_function(struct Sdk* sdk)
{
// Make your application do something from within this plugin.
sdk->do_something(123);
}
Inoltre, utilizzerei effettivamente un'API C (sebbene tu possa implementare le funzioni C in C ++). C è il linguaggio più standardizzato per le API. Se usi C, puoi persino chiamare quelle funzioni C da una vasta gamma di linguaggi di programmazione e consentire ai tuoi clienti, ad esempio, di implementare i loro plug-in in C #. Potrebbero quindi creare come una libreria YourSoftware.Net
che consente di utilizzare l'API C in modo idiomatico rispetto alle lingue e al framework .NET
, così come hanno fatto le persone con, ad esempio, OpenGL
. Non è così tanto se crei un'API C ++ soggetta a più problemi del vendor che mancano di uno standard ABI, il mangling dei nomi dei simboli esportati per l'overloading delle funzioni che potrebbe essere molto specifico per il compilatore e fugly da importare proprio per lo meno, eccezioni che non possono essere gettate in modo sicuro attraverso i limiti del modulo, digitare funzionalità come fotocopiatori e dorsali che alcune lingue non sapranno cosa fare con, ecc.
Allo stesso modo è possibile costruire una libreria C ++ statica in alto che avvolge l'API C e la trasforma in codice C ++ idiomatico (es: traducendo i codici di errore in eccezioni, trasformando le risorse C che devono essere liberate manualmente in oggetti C ++ conformi a RAII con distruttori, puntatori di funzioni in funzioni virtuali, ecc.)
Questo richiede tempo e pensiero, soprattutto se è la prima volta che lo fai, ma è il modo principale con cui vengono create le architetture di estensibili plug-in ei vantaggi di farlo correttamente, se necessario, superano spesso i costi a lungo termine.
Un'altra opzione è incorporare un linguaggio di scripting nella tua applicazione, come Lua. Quindi i tuoi clienti possono scrivere il codice Lua che chiama le funzioni dell'applicazione in fase di esecuzione e puoi anche avere una console di scripting direttamente all'interno del tuo software in cui i tuoi clienti possono digitare il codice ed eseguirlo al volo senza riavviare l'applicazione. Ciò comporta anche la sua quota di lavoro anticipato, anche se tende a essere costoso o addirittura più che progettare un C SDK, ma ti permette di fare cose davvero interessanti con il tuo software in fase di runtime e può davvero aiutare molto a testare le sue funzioni a runtime al volo anche se preferisci scrivere la maggior parte del codice in C ++.
I'm concerned about mixing debug and release code, though, as if I
deliver debug files perhaps my source code and implementation will be
available to them but it I deliver only release mode .lib files then
perhaps they won't be able to debug without issues.
Penso che questa sia una preoccupazione poco pratica. Se sto scrivendo plugin per Google Chrome, non mi interessa il debug del codebase di Google Chrome, solo il codice per il mio plugin. Molto probabilmente i tuoi clienti non saranno così interessati a esaminare i dettagli di implementazione della tua base di codice proprio come non sei interessato a farglielo vedere. Il solito modo è di dare ai binari di rilascio dei client. Scrivono plugin e possono creare versioni di debug di questi e eseguono il debug e la traccia attraverso il proprio codice estendendo le funzionalità dell'applicazione, ma non si preoccupano di eseguire il debug del codice e tracciare le chiamate API.