Codice di limitazione nel codice di debug consegnato al cliente

1

Sto progettando alcuni software che verranno consegnati a un cliente con alcune aree limitate che possono personalizzare utilizzando la stessa piattaforma e compilatore (Windows 10, Visual Studio 2017). Il mio obiettivo è consentire loro di ereditare da una classe e generare dati dalla loro fonte proprietaria e trasmetterli al sistema principale.

Vorrei che il codice che consegnamo --- tranne la parte personalizzabile --- fosse chiuso e non disponibile al cliente. Inizialmente pensavo di fornire un set di file .lib e di permettere loro di usare queste librerie. Sono preoccupato di mixare il debug e il codice di rilascio, anche se, come se consegnassi i file di debug, forse il codice sorgente e l'implementazione saranno disponibili per loro, ma fornirò solo i file .lib di rilascio, quindi forse non saranno in grado di eseguire il debug senza problemi.

D'altra parte, se recapito i file DLL, forse dovrò dedicare un po 'più tempo alle interfacce e mi preoccupo che assegnino memoria per i dati e che io debba liberarlo (vedi here , ad esempio).

Per Windows e Visual Studio 2017, esiste un modo standard per implementare questo tipo di accordo in cui il cliente può implementare funzionalità aggiunte mantenendo nascosto un certo codice proprietario?

Alcune opzioni sono rilasciate solo .lib / dll o tentano di configurare una build di debug che non contenga informazioni di debug.

    
posta Steve 20.11.2017 - 23:18
fonte

1 risposta

1

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.

    
risposta data 28.11.2017 - 21:08
fonte

Leggi altre domande sui tag