none
Export a STL object from dll

    Question

  • My question is very simple. How to correctly export class with STL objects from DLL without warnings 4251 and access violation exceptions. I get warnings to private variables of my dll class and get an exceptions when call all dll functions.

    Debug - /MTd

    dll (header):

    class __declspec(dllexport) MyClass
    {
        public:
           map<string, string> var1;
           void method1();
           void set();
           string get();
        private string var2;
    };

    dll (source):

    MyClass::MyClass()
    {}

    MyClass::~MyClass()
    {}

    void MyClass::method1()
    {
         //do something with var1...
    }

    void MyClass::set(string str)
    {
         var2 = str;
    }

    string MyClass::get()
    {
         return var2;
    }

    exe:

    MyClass myclass;

    string var = myclass.get();  //exception
    myclass.set(var);               //exception
    myclass.method1();           //exception


    Its an estimate of the structure for understanding issue.

    Thank's

    Tuesday, December 15, 2009 11:44 AM

Answers

  • Permit me to emphasize what Giovanni has suggested. Exporting STL containers is a very bad idea. It will force you to ensure that the compiler used to compile both the DLL and the client code be exactly the same version, and also use exactly the same compiler settings. It sets the stage for very fragile development. Furthermore, I've never heard of exporting class member functions..... I don't even know if they would work since there is an implied "this" that must be passed as the first parameter.

    Wipe that whiteboard clean and start over.

    • Marked as answer by Nancy Shao Tuesday, December 22, 2009 3:49 AM
    Tuesday, December 15, 2009 4:53 PM

All replies

  • I think that your problems are caused by the fact that you use /MT[d], i.e. you are statically linking with CRT.
    Instead, you should use /MD[d] , i.e. use multithreaded DLL version of runtime library, i.e. dynamically link to CRT.

    In fact, for example, objects created by your DLL and the client EXE should share the same common heap.

    However, note that passing C++ classes at DLL boundaries (including STL classes) is very constraining.
    In fact, you should use the same C++ compiler, with the same compiler options, etc.
    (Those constraints seem somewhat similar to those of static linking...)

    IMHO, the most robust ways of creating native DLLs are implementing DLLs with pure C interface (of course, you can use C++ inside the DLL, but pay attention that e.g. C++ exceptions do not cross DLL boundaries), or use COM .

    Giovanni
    Tuesday, December 15, 2009 12:12 PM
  • Thank's for answer.
    I have a MFC project and MFC dll (i use MFC as static library). First i write it on VS 6.0. But now i port it on VS 2008. When i write header of dll as:

    class  MyClass
    {
        public:
           map<string, string> var1;
           __declspec(dllexport) void method1();
           __declspec(dllexport) void set();
           __declspec(dllexport) string get();
        private string var2;
    };

    I haven't exceptions and warning but this methods not works. For example string variable not save the state when return from method. I spent time to solve problem and think that it causes by incorrect export of my dll.
    Tuesday, December 15, 2009 1:26 PM
  • I also read MSDN articles but methods in this articles applies to Visual C++ 6.0, but i use 2008 studio. And i also read, that create objects of dll classes in .exe application source incorrect. Object must be created in dll source.
    Tuesday, December 15, 2009 1:33 PM
  • Permit me to emphasize what Giovanni has suggested. Exporting STL containers is a very bad idea. It will force you to ensure that the compiler used to compile both the DLL and the client code be exactly the same version, and also use exactly the same compiler settings. It sets the stage for very fragile development. Furthermore, I've never heard of exporting class member functions..... I don't even know if they would work since there is an implied "this" that must be passed as the first parameter.

    Wipe that whiteboard clean and start over.

    • Marked as answer by Nancy Shao Tuesday, December 22, 2009 3:49 AM
    Tuesday, December 15, 2009 4:53 PM
  • Thank you, Brian. If i understand you right, if i write a dll i must use only MFC classes and objects (if i have MFC dll) or pure C interface (use C-style WinAPI functions). STL containers, in this case, i must use on client. And generally, i must export whole class, such as

    class __declspec(dllexport) MyClass {};

    Thank's
    Tuesday, December 15, 2009 5:55 PM
  • if i write a dll i must use only MFC classes and objects (if i have MFC dll) or pure C interface (use C-style WinAPI functions)

    Just to be clear, "must" is too strong a word. It's possible, and not uncommon, to export classes; there are just many restrictions that makes doing so error-prone, so Brian is wisely suggesting that you try to come up with a design that avoids doing so.
    Tuesday, December 15, 2009 6:06 PM
  • These links may help

    http://support.microsoft.com/kb/168958/

    http://support.microsoft.com/kb/172396

    Thursday, April 01, 2010 6:21 AM