Frage

Ich habe eine DLL, die Daten müssen in STL-Containern in der Host-Anwendung gespeichert sind, zugreifen. Da C ++ keinen Standard ABI hat, und ich mag verschiedene Compiler unterstützt, ist die Schnittstelle zwischen der Anwendung und DLL im Grunde plain-old-Daten bleiben muss.

Für Vektoren ist dies relativ einfach. Sie können einfach den Speicherblock des Vektors zurückkehren, weil es garantiert sein 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();
}

Nun kann die DLL sicher Nur-Lese-Zugriff auf die Daten des Vektors über diese Schnittstelle. Die DLL kann auch diese wickeln Sie den Inhalt in einen Vektor für sich selbst als auch zu kopieren.

Was ist STL-Listen (und deques), obwohl? Gibt es eine andere einfache Möglichkeit, den Zugriff über eine DLL-Grenze zu erlauben? Oder muss ich auf eine Art GetFirst () / GetNext () Schnittstelle greifen? Ich könnte müssen diese Listen für viel zu tun, so dass es wäre schön, eine Lösung so einfach wie Vektors zu haben.

War es hilfreich?

Lösung

Vielleicht können Sie so etwas wie „Griffe“ zur Liste / deque Iteratoren übergeben? Diese Grifftypen wäre undurchsichtig und erklärt in einer Header-Datei, die Sie an die Benutzer versendet würde. Intern müßten Sie den Griff Werte abzubilden zur Liste / deque Iteratoren. Grundsätzlich würde der Benutzer schreibt Code wie:

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

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

Andere Tipps

Sie können stl Objekte zwischen DLLs übergeben und verschiedene Compiler unterstützen, wenn Sie vorsichtig sind, wo Sie jeden stl Typ instanziiert. Sie müssen einige intelligente „Dllexport“ Makros - ich verwende die erfolgreich gesetzt folgenden VC und gcc unterstützen

.
#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

Wenn Ihre DLL kompilieren, definieren MYDLLLIB_EXPORTS. In der DLL können Sie dann jeden stl Typ instanziiert Sie verwenden möchten, zum Beispiel Listen oder Vektoren von Strings

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

Die Verbraucher Ihrer DLL (die nicht über MYDLLLIB_EXPORTS definiert) werden dann sehen,

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

und verwenden Sie den binären Code aus der DLL exportiert stattdessen ihre eigenen instanziieren.

  

die Schnittstelle zwischen der Anwendung   und DLL hat im Grunde zu bleiben   plain-old-Daten.

Nicht unbedingt. Sie müssen sicher sein, dass die gleiche Compiler-Version verwendet wird. Außerdem bauen Einstellungen, die das Layout der STL-Objekte beeinflussen ist genau das gleiche zwischen den DLL und Anwendung.

Wenn Sie die DLL in die Wildnis entlassen sind, sind Sie hier richtig mit betroffen sein STL über dll Grenzen auszusetzen. Wenn jedoch alles unter Kontrolle und rein internen (oder wenn Sie starr dritte Partei aufbauen Einstellungen / Compiler erzwingen können) sollten Sie in Ordnung sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top