Domanda

Ho una DLL che ha bisogno di accedere ai dati memorizzati in contenitori STL nell'applicazione host. A causa C ++ non ha standard di ABI, e voglio supportare diversi compilatori, l'interfaccia tra l'applicazione e DLL ha sostanzialmente rimanere-old-dati pianura.

Per i vettori questo è relativamente semplice. Si può semplicemente restituire il blocco di memoria del vettore, perché è garantito per essere contigious:

// To return vector<int> data
virtual void GetVectorData(const int*& ptr, size_t& count) const
{
    if (!vec.empty())
        ptr = &(vec.front());

    count = vec.size();
}

Ora la DLL può avere sicuro accesso in sola lettura ai dati del vettore tramite l'interfaccia. La DLL può anche avvolgere questo per copiare il contenuto in un vettore per se stesso come bene.

Che dire di liste STL (e deque), anche se? C'è un altro modo semplice per consentire l'accesso tramite un confine DLL? Oppure dovrò ricorrere a qualche tipo di interfaccia GetFirst () / GetNext ()? Potrei bisogno di fare questo per un sacco di liste, per cui sarebbe bello avere una soluzione semplice come vettore di.

È stato utile?

Soluzione

Forse si può passare qualcosa come "maniglie" per elencare / iteratori deque? Questi tipi manico sarebbero opaco e dichiarata in un file di intestazione si dovrebbe spedire agli utenti. Internamente, si avrebbe bisogno di mappare i valori di handle per elencare / iteratori deque. In sostanza, l'utente dovrebbe scrivere codice come:

ListHandle lhi = GetListDataBegin();
const ListHandle lhe = GetListDataEnd();

while (lhi != lhe)
{
  int value = GetListItem(lhi);
  ...
  lhi = GetNextListItem(lhi);
}

Altri suggerimenti

È possibile passare oggetti STL tra DLL e supportare diversi compilatori se siete attenti dove si crea un'istanza di ogni tipo STL. Avete bisogno di alcune macro intelligenti "dllexport" - Io uso il seguente set di supportare con successo VC e gcc

.
#ifdef WIN32
#ifdef MYDLLLIB_EXPORTS      // DLL export macros
#define MYDLLLIB_API __declspec(dllexport)
#define MYDLLLIB_TEMPLATE
#else
#define MYDLLLIB_API __declspec(dllimport)
#define MYDLLLIB_TEMPLATE extern
#endif
#else                       // Not windows --- probably *nix/bsd
#define MYDLLLIB_API
#ifdef MYDLLLIB_EXPORTS
#define MYDLLLIB_TEMPLATE
#else
#define MYDLLLIB_TEMPLATE extern
#endif
#endif // WIN32

Quando si compila la DLL, definire MYDLLLIB_EXPORTS. Nella DLL si può quindi istanziare ogni tipo STL che si desidera utilizzare, ad esempio, elenchi o vettori di stringhe

MYDLLLIB_TEMPLATE template class MYDLLLIB_API std::vector<std::string>;
MYDLLLIB_TEMPLATE template class MYDLLLIB_API std::list<std::string>;

I consumatori di DLL (che non hanno MYDLLLIB_EXPORTS definiti) saranno poi vedere

extern template class __declspec(dllimport) std::vector<std::string>;

e utilizzare il codice binario esportata dalla DLL, invece di istanziare propria.

  

l'interfaccia tra l'applicazione   e DLL ha fondamentalmente restare   plain-old-dati.

Non necessariamente. Dovete essere sicuri che la stessa versione del compilatore viene utilizzato. Inoltre, costruire le impostazioni che influiscono la disposizione degli oggetti STL è esattamente lo stesso tra la dll e l'applicazione.

Se si dovesse rilasciare il dll fuori in libertà, lei ha ragione ad essere preoccupati di esporre STL attraverso i confini DLL. Se, invece, tutto è sotto il vostro controllo e puramente interna (o se si può far rispettare rigidamente 3rd party costruire impostazioni / compilatore) si dovrebbe andare bene.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top