HomeBlogMagic

__declspec(export) von Templates innerhalb einer Klasse

Einige Klassen die ich benutze benötigen eigene interne Strukturen um Daten z.B. in Listen ablegen zu können.
Wenn diese Strukturen nur im Zusammenhang mit dieser Klasse gebraucht werden, dann definiere ich diese gerne innerhalb der Klasse

Als Klassisches Beispiel hierfür nehme ich z.B. eine Benutzer Liste die nur innerhalb einer Klasse existiert:

class CUserConfig
{
  public:
    class CUser
    {
      std::string sUserName;
      std::string sPassword;
    };

    const CUserConfig& getUser(int iPosition) const
    { return m_oUserList[i]; }

  private:
    std::vector<CUserConfig> m_oUserList;
    std::string              m_oAdmin;
};

Wäre diese Klasse nur private und würde nicht exportiert werden, dann wären wir mit der Implementierung soweit fertig. Wenn diese Klasse allerdings in einer Bibliothek angelegt wird, welche von einer anderen Anwendung referenziert wird, dann müssen wir diese Klasse noch exportieren.
Hier wird es etwas schwieriger da der Microsoft C++ Compiler das etwas komplizierter macht.

Um die std::vector exportieren zu können muss diese erst einen eigenen Typen bekommen:

typedef std::vector<CUserConfig> CUserList;

Durch diese definition kann der MSC diese liste nun exportieren mit:

class __declspec(dllexport) CUserList;

Nachdem es mir ein paar mal passiert ist dass die CUserList nur teilweise exportiert wurde, musste ich noch folgendes außerhalb der Klasse ergänzen:

template class __declspec(dllexport)std::vector<CUserConfig::CUser>;

Im Anschluss kann das typedef auch für den Member benutzt werden.
Die ganze Klasse sieht dann wie folgt aus:

#ifdef EXPORT
  #define SHARE __declspec(dllexport)
#else
  #define SHARE __declspec(dllimport)
#endif

class SHARE CUserConfig
{
  public:
    class SHARE CUser
    {
      std::string sUserName;
      std::string sPassword;
    };

    typedef class SHARE std::vector<CUser> CUserList;

    const CUserConfig& getUser(int iPosition) const
    { return m_oUserList[i]; }

    CUserList     m_oUserList;
    std::string   m_oAdmin;
};

template class SHARE std::vector<CUserConfig::CUser>;
Permalink: https://adirmeier.de/Blog/ID_389
Tags: Blog, C/C++, class, libvon am 2021-12-22