Best practice per il salvataggio dello stato in un oggetto condiviso C ++

6

Per sviluppare una libreria C ++ collegata dinamicamente (cioè un oggetto condiviso) che possa interfacciarsi con i programmi C, qual è la migliore pratica per salvare lo stato del programma tra le chiamate di funzione esportate?

Io come programmatore C ++ non esperto posso pensare ai seguenti metodi:

  • Livello unità di compilazione static variabili.
  • Crea un'istanza di struct all'heap che detiene lo stato e passa il suo indirizzo indietro in ogni chiamata API (un po 'come JNI).

Il problema con il primo approccio è che le mie variabili di stato necessitano di alcuni dati da inizializzare e questi dati sono forniti chiamando init API (una delle funzioni esportate). Dall'altro lato, quando si utilizzano le variabili di livello static del modulo, quei dati non sono ancora disponibili quando tali variabili vengono inizializzate.

Anche il mio problema con il secondo metodo è che ogni funzione API dovrebbe essere fornita con quel puntatore e questo è un po 'macchinoso.

Si noti che esiste un'altra opzione che le variabili static sono puntatori a quelle variabili di stato e sono assegnate in quella funzione init (in realtà le variabili di stato sono istanziate in init e il loro indirizzo sono salvato in quelle variabili statiche). Questa opzione va bene, ma non vorrei usare puntatori dove possibile.

    
posta Hi I'm Frogatto 09.01.2017 - 17:19
fonte

1 risposta

10

Passare un puntatore a un oggetto di stato è probabilmente la soluzione migliore. Perché?

Lo stato delle tue funzioni è reso esplicito e ovvio. È la soluzione più generale e più estensibile.

Sfortunatamente, le API con uno stato globale (nascosto) sono abbastanza comuni. Tendono a semplificare le cose semplici, ma spesso rendono le cose più difficili completamente impossibili.

es. immagina una libreria client del database. Per accedere a un database, è necessario prima creare una connessione. Cosa succede se desidero connettermi a più database contemporaneamente? Se c'è una singola connessione globale nascosta nella libreria, questo è assolutamente impossibile.

Passare un parametro in più è un po ' fastidioso. Ma finché tutto lo stato è raggruppato in un singolo oggetto che deve essere portato in giro, non è molto fastidioso.

Anche se decidessi di mantenere uno stato globale nascosto, raggrupperei quello stato in un singolo oggetto in modo che diventi più facile da gestire. Tenere traccia di più variabili globali correlate è abbastanza soggetto a errori, controllare se una singola variabile globale è stata inizializzata è molto più facile. Tieni presente che con uno stato globale nascosto, dovrai verificare se lo stato è impostato in ciascuna funzione esportata per evitare errori degli utenti.

    
risposta data 09.01.2017 - 19:15
fonte

Leggi altre domande sui tag