How to expose STL list over DLL boundary?

后端 未结 3 755
情话喂你
情话喂你 2021-02-02 02:42

I have a DLL which needs to access data stored in STL containers in the host application. Because C++ has no standard ABI, and I want to support different compilers, the interf

相关标签:
3条回答
  • 2021-02-02 03:31

    the interface between the application and DLL basically has to remain plain-old-data.

    Not necessarily. You have to be sure that the same compiler version is used. Also, build settings that impact the layout of the STL objects is exactly the same between the dll and application.

    If you were to release the dll out into the wild, you are right to be concerned with exposing STL across dll boundaries. If, however, everything is under your control and purely internal (or if you can rigidly enforce 3rd party build settings/compiler) you should be fine.

    0 讨论(0)
  • 2021-02-02 03:38

    Perhaps you can pass something like "handles" to list/deque iterators? These handle types would be opaque and declared in a header file you would ship to the users. Internally, you would need to map the handle values to list/deque iterators. Basically, the user would write code like:

    ListHandle lhi = GetListDataBegin();
    const ListHandle lhe = GetListDataEnd();
    
    while (lhi != lhe)
    {
      int value = GetListItem(lhi);
      ...
      lhi = GetNextListItem(lhi);
    }
    
    0 讨论(0)
  • 2021-02-02 03:43

    You can pass stl objects between DLLs and support different compilers if you are careful where you instantiate each stl type. You need some intelligent "DLLEXPORT" macros -- I use the following set to successfully support VC and 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
    

    When compiling your DLL, define MYDLLLIB_EXPORTS. In the DLL you can then instantiate each stl type you wish to use, for example, lists or vectors of strings

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

    Consumers of your DLL (who don't have MYDLLLIB_EXPORTS defined) will then see

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

    and use the binary code exported from your DLL instead of instantiating their own.

    0 讨论(0)
提交回复
热议问题