Question

J'ai une DLL qui a besoin d'accéder aux données stockées dans des conteneurs STL dans l'application hôte. Parce que C ++ n'a pas ABI standard, et je veux soutenir différents compilateurs, l'interface entre l'application et la DLL a essentiellement rester plaine ancienne des données.

Pour les vecteurs ce qui est relativement simple. Vous pouvez simplement retourner le bloc de mémoire du vecteur, car il est garanti 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();
}

Maintenant, la DLL peut avoir accès en toute sécurité en lecture seule aux données du vecteur via cette interface. La DLL peut également envelopper ceci pour copier le contenu dans un vecteur pour elle-même.

Qu'en est-il des listes STL (et Deques), bien? Est-il un autre moyen simple pour permettre l'accès par l'intermédiaire d'une limite de DLL? Ou vais-je avoir recours à une sorte d'interface GetFirst () / GetNext ()? Je pourrais avoir besoin de faire cela pour un grand nombre de listes, il serait bien d'avoir une solution aussi simple que de vecteur.

Était-ce utile?

La solution

Peut-être que vous pouvez passer quelque chose comme « poignées » à la liste / deque itérateurs? Ces types de poignées seraient opaques et a déclaré dans un fichier d'en-tête vous expédier aux utilisateurs. En interne, vous devez mapper les valeurs de poignée à la liste / itérateurs deque. En gros, l'utilisateur d'écrire du code comme:

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

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

Autres conseils

Vous pouvez passer des objets stl entre DLL et de soutenir différents compilateurs si vous faites attention où vous instancier chaque type stl. Vous avez besoin des macros « de dllexport » intelligents - j'utiliser ce qui suit pour soutenir avec succès mis en VC et 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

Lors de la compilation de votre DLL, définissez MYDLLLIB_EXPORTS. Dans la DLL, vous pouvez alors instancier chaque type de stl que vous souhaitez utiliser, par exemple, des listes ou des vecteurs de chaînes

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

Les consommateurs de votre DLL (qui n'ont pas MYDLLLIB_EXPORTS définies) seront alors voir

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

et utiliser le code binaire exporté à partir de votre DLL au lieu de leur propre instanciation.

  

l'interface entre l'application   et DLL a essentiellement rester   plaine vieux données.

Pas nécessairement. Vous devez être sûr que la même version du compilateur est utilisé. , Construire également des paramètres qui influent sur la mise en page des objets STL est exactement la même entre le dll et l'application.

Si vous deviez libérer le dll dehors dans la nature, vous avez raison d'être concernés par l'exposition STL à travers les frontières dll. Cependant, si tout est sous votre contrôle et purement interne (ou si vous pouvez appliquer de manière rigide 3ème partie paramètres de construction / compilateur), vous devriez être très bien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top