exporting a C++ object in a DLL

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Grey Alien

    exporting a C++ object in a DLL

    I have a class that contains a std::map variable. I need to export the
    class via a DLL. the class looks something like this:

    class MyClass
    {
    public:
    MyClass();
    MyClass(const MyClass&);

    private:
    MyClass& operator=(const MyClass&);

    typedef std::map<SomeKe y, SomethingElseTr easureChest ;

    TreasureChest m_treasures;
    };


  • QbProg

    #2
    Re: exporting a C++ object in a DLL

    you can either __declspec(dlle xport) every member of the class that
    you want to export, or __declspec(dlle xport) the class definition.

    In the "dll user" code you should declare the class with
    __declspec(dlli mport). There are standard ways to do that using
    macros. See


    or


    Good Bye
    QbProg

    Comment

    • Grey Alien

      #3
      Re: exporting a C++ object in a DLL



      QbProg wrote:
      you can either __declspec(dlle xport) every member of the class that
      you want to export, or __declspec(dlle xport) the class definition.
      >
      In the "dll user" code you should declare the class with
      __declspec(dlli mport). There are standard ways to do that using
      macros. See

      >
      or

      >
      Good Bye
      QbProg
      >
      See: http://support.microsoft.com/kb/168958

      Relevant text: The only STL container that can currently be exported is
      vector. The other containers (that is, map, set, queue, list, deque) all
      contain nested classes and cannot be exported.

      The article was last reviewed in September 2005 - I wanted to know if it
      is now possible to export std::map from a DLL

      Comment

      • Ben Voigt [C++ MVP]

        #4
        Re: exporting a C++ object in a DLL


        "Grey Alien" <grey@andromeda .comwrote in message
        news:uYqdnRk5Zq jPFxrbRVnyggA@b t.com...
        >I have a class that contains a std::map variable. I need to export the
        >class via a DLL. the class looks something like this:
        No you don't. Create an interface (class with pure virtual pointers),
        derive the implementation from it, and share only the interface. You do
        that by putting the interface definition in a public header file. No
        __declspec(dlle xport) statement is needed.

        Exporting C++ classes is very bad news. __declspec(dlle xport) should be
        used only for 'extern "C"' functions.
        >
        class MyClass
        {
        public:
        MyClass();
        MyClass(const MyClass&);
        >
        private:
        MyClass& operator=(const MyClass&);
        >
        typedef std::map<SomeKe y, SomethingElseTr easureChest ;
        >
        TreasureChest m_treasures;
        };
        >
        >

        Comment

        • Grey Alien

          #5
          Re: exporting a C++ object in a DLL



          Ben Voigt [C++ MVP] wrote:
          "Grey Alien" <grey@andromeda .comwrote in message
          news:uYqdnRk5Zq jPFxrbRVnyggA@b t.com...
          >
          >>I have a class that contains a std::map variable. I need to export the
          >>class via a DLL. the class looks something like this:
          >
          >
          No you don't.
          Yes I do. I know what I want.

          Create an interface (class with pure virtual pointers),
          derive the implementation from it, and share only the interface. You do
          that by putting the interface definition in a public header file. No
          __declspec(dlle xport) statement is needed.
          You are assuming that the DLL will be consumed by a C++ client. That is
          not the case. Besides, how can you possibly use code in another
          compilation unit if you don't link into it (either statically or
          dynamically).?
          >
          Exporting C++ classes is very bad news. __declspec(dlle xport) should be
          used only for 'extern "C"' functions.
          Not necessarily true. In my case, I am taking care of the C++ "name
          mangling" - through various policies and procedures (didn't include info
          because it is orthogonal to my original question).
          >
          >
          >>class MyClass
          >>{
          >>public:
          > MyClass();
          > MyClass(const MyClass&);
          >>
          >>private:
          > MyClass& operator=(const MyClass&);
          >>
          > typedef std::map<SomeKe y, SomethingElseTr easureChest ;
          >>
          > TreasureChest m_treasures;
          >>};
          >>
          >>
          >
          >
          >

          Comment

          • David Wilkinson

            #6
            Re: exporting a C++ object in a DLL

            Grey Alien wrote:
            You are assuming that the DLL will be consumed by a C++ client. That is
            not the case. Besides, how can you possibly use code in another
            compilation unit if you don't link into it (either statically or
            dynamically).?
            Grey:

            You want to export a class containing an std::map and it will not be
            consumed by a C++ client?

            Ben's advice might have seemed a little fierce, but basically I agree
            with it. You will save yourself a lot of future headaches if you design
            your class with a pure virtual interface (and methods using simple types).

            --
            David Wilkinson
            Visual C++ MVP

            Comment

            • Grey Alien

              #7
              Re: exporting a C++ object in a DLL



              David Wilkinson wrote:
              Grey Alien wrote:
              >
              >You are assuming that the DLL will be consumed by a C++ client. That
              >is not the case. Besides, how can you possibly use code in another
              >compilation unit if you don't link into it (either statically or
              >dynamically) .?
              >
              >
              Grey:
              >
              You want to export a class containing an std::map and it will not be
              consumed by a C++ client?
              >
              Ben's advice might have seemed a little fierce, but basically I agree
              with it. You will save yourself a lot of future headaches if you design
              your class with a pure virtual interface (and methods using simple types).
              >
              Dave:

              That may be the case, but the fact remains that the class whose methods
              are invoked needs to contain a map member variable. At the moment, I'm
              getting this annoying warning:

              warning C4251: 'theManager::m_ signalMap' : class 'std::map<_Kty, _Ty>'
              needs to have dll-interface to be used by clients of class 'theManager'

              - which seems to imply that std::map can be exported - which contradicts
              the (outdated) article on the MSN site. So do I heed the warning and
              export the data type (preferred) or do ignore it (with potentially
              disastrous consequences)?

              Comment

              • Grey Alien

                #8
                Re: exporting a C++ object in a DLL

                Never mind, I found the solution here:

                Comment

                • Ben Voigt [C++ MVP]

                  #9
                  Re: exporting a C++ object in a DLL


                  "Grey Alien" <grey@andromeda .comwrote in message
                  news:1tGdnWRjLK YbjRTbnZ2dnUVZ8 turnZ2d@bt.com. ..
                  >
                  >
                  Ben Voigt [C++ MVP] wrote:
                  >"Grey Alien" <grey@andromeda .comwrote in message
                  >news:uYqdnRk5Z qjPFxrbRVnyggA@ bt.com...
                  >>
                  >>>I have a class that contains a std::map variable. I need to export the
                  >>>class via a DLL. the class looks something like this:
                  >>
                  >>
                  >No you don't.
                  >
                  Yes I do. I know what I want.
                  >
                  Create an interface (class with pure virtual pointers),
                  >derive the implementation from it, and share only the interface. You do
                  >that by putting the interface definition in a public header file. No
                  >__declspec(dll export) statement is needed.
                  >
                  You are assuming that the DLL will be consumed by a C++ client. That is
                  not the case. Besides, how can you possibly use code in another
                  compilation unit if you don't link into it (either statically or
                  dynamically).?
                  If your client isn't C++, the prohibition on __declspec(dlle xport) of
                  classes becomes absolutely instead of just a really good idea.

                  What do you mean by "don't link into it"? You are creating a DLL, right?
                  "dynamicall y linked library" If you create an interface, then the compiler
                  links the interface v-table to the implementations . The client only needs
                  the interface definition.

                  Comment

                  • Ben Voigt [C++ MVP]

                    #10
                    Re: exporting a C++ object in a DLL


                    "Grey Alien" <grey@andromeda .comwrote in message
                    news:pKudnegyaI _TrhTbnZ2dnUVZ8 sGvnZ2d@bt.com. ..
                    >
                    >
                    David Wilkinson wrote:
                    >
                    >Grey Alien wrote:
                    >>
                    >>You are assuming that the DLL will be consumed by a C++ client. That is
                    >>not the case. Besides, how can you possibly use code in another
                    >>compilation unit if you don't link into it (either statically or
                    >>dynamically). ?
                    >>
                    >>
                    >Grey:
                    >>
                    >You want to export a class containing an std::map and it will not be
                    >consumed by a C++ client?
                    >>
                    >Ben's advice might have seemed a little fierce, but basically I agree
                    >with it. You will save yourself a lot of future headaches if you design
                    >your class with a pure virtual interface (and methods using simple
                    >types).
                    >>
                    >
                    Dave:
                    >
                    That may be the case, but the fact remains that the class whose methods
                    are invoked needs to contain a map member variable. At the moment, I'm
                    getting this annoying warning:
                    >
                    warning C4251: 'theManager::m_ signalMap' : class 'std::map<_Kty, _Ty>'
                    needs to have dll-interface to be used by clients of class 'theManager'
                    - which seems to imply that std::map can be exported - which contradicts
                    the (outdated) article on the MSN site. So do I heed the warning and
                    export the data type (preferred) or do ignore it (with potentially
                    disastrous consequences)?
                    There is no contradiction, both are correct. std::map should not be
                    exported, and because of that, it should not be used by clients of
                    "theManager ". Since it is a private implementation detail, why would that
                    present a problem? Clients aren't using it.

                    Comment

                    • Grey Alien

                      #11
                      Re: exporting a C++ object in a DLL



                      Ben Voigt [C++ MVP] wrote:
                      >
                      "Grey Alien" <grey@andromeda .comwrote in message
                      news:1tGdnWRjLK YbjRTbnZ2dnUVZ8 turnZ2d@bt.com. ..
                      >
                      >>
                      >>
                      >Ben Voigt [C++ MVP] wrote:
                      >>
                      >>"Grey Alien" <grey@andromeda .comwrote in message
                      >>news:uYqdnRk5 ZqjPFxrbRVnyggA @bt.com...
                      >>>
                      >>>I have a class that contains a std::map variable. I need to export
                      >>>the class via a DLL. the class looks something like this:
                      >>>
                      >>>
                      >>>
                      >>No you don't.
                      >>
                      >>
                      >Yes I do. I know what I want.
                      >>
                      > Create an interface (class with pure virtual pointers),
                      >>
                      >>derive the implementation from it, and share only the interface. You
                      >>do that by putting the interface definition in a public header file.
                      >>No __declspec(dlle xport) statement is needed.
                      Sounds like you're describing the Pimpl pattern. I haven't used it
                      myself before, though it does sound like a good idea (I can't use it in
                      my current project though - because legacy code already exports classes).

                      However, as a matter of interest, if only the interface is specified
                      (via pure virtuals in a header) - surely, it means that EACH child class
                      will have to implement the same functionality allover again. The idea
                      for exporting classes was for code reuse - which you seem to be losing,
                      using the Pimpl pattern you describe. Am I missing something?

                      Comment

                      • David Wilkinson

                        #12
                        Re: exporting a C++ object in a DLL

                        Grey Alien wrote:
                        Sounds like you're describing the Pimpl pattern. I haven't used it
                        myself before, though it does sound like a good idea (I can't use it in
                        my current project though - because legacy code already exports classes).
                        Grey:

                        Pimpl and Abstract Base Class (ABC) are not the same thing. A pimpl
                        class is not a pure interface.

                        --
                        David Wilkinson
                        Visual C++ MVP

                        Comment

                        • Ben Voigt [C++ MVP]

                          #13
                          Re: exporting a C++ object in a DLL


                          "Grey Alien" <grey@andromeda .comwrote in message
                          news:rJednYCB69 R-OxbbnZ2dnUVZ8qS nnZ2d@bt.com...
                          >
                          >
                          Ben Voigt [C++ MVP] wrote:
                          >
                          >>
                          >"Grey Alien" <grey@andromeda .comwrote in message
                          >news:1tGdnWRjL KYbjRTbnZ2dnUVZ 8turnZ2d@bt.com ...
                          >>
                          >>>
                          >>>
                          >>Ben Voigt [C++ MVP] wrote:
                          >>>
                          >>>"Grey Alien" <grey@andromeda .comwrote in message
                          >>>news:uYqdnRk 5ZqjPFxrbRVnygg A@bt.com...
                          >>>>
                          >>>>I have a class that contains a std::map variable. I need to export the
                          >>>>class via a DLL. the class looks something like this:
                          >>>>
                          >>>>
                          >>>>
                          >>>No you don't.
                          >>>
                          >>>
                          >>Yes I do. I know what I want.
                          >>>
                          >> Create an interface (class with pure virtual pointers),
                          >>>
                          >>>derive the implementation from it, and share only the interface. You
                          >>>do that by putting the interface definition in a public header file.
                          >>>No __declspec(dlle xport) statement is needed.
                          >
                          Sounds like you're describing the Pimpl pattern. I haven't used it myself
                          before, though it does sound like a good idea (I can't use it in my
                          current project though - because legacy code already exports classes).
                          >
                          However, as a matter of interest, if only the interface is specified (via
                          pure virtuals in a header) - surely, it means that EACH child class will
                          have to implement the same functionality allover again. The idea for
                          exporting classes was for code reuse - which you seem to be losing, using
                          the Pimpl pattern you describe. Am I missing something?
                          Yup. The interface can be implemented in a base class which provides the
                          implementation, and each derived (or child if you prefer) class inherits.
                          Only the interface cannot have any implementation, but it can participate in
                          a full hierarchy.

                          Comment

                          • Grey Alien

                            #14
                            Re: exporting a C++ object in a DLL



                            Ben Voigt [C++ MVP] wrote:
                            >
                            >However, as a matter of interest, if only the interface is specified
                            >(via pure virtuals in a header) - surely, it means that EACH child
                            >class will have to implement the same functionality allover again. The
                            >idea for exporting classes was for code reuse - which you seem to be
                            >losing, using the Pimpl pattern you describe. Am I missing something?
                            >
                            >
                            Yup. The interface can be implemented in a base class which provides
                            the implementation, and each derived (or child if you prefer) class
                            inherits. Only the interface cannot have any implementation, but it can
                            participate in a full hierarchy.
                            But if the interface is implemented in a base class, then that base
                            class needs to be exported, so that its derived classes can correctly
                            link to the approriate compilation units - so we end up in the same
                            situation, i.e having to export the (base) class.

                            Unless I am misunderstandin g you, your approach ensures that if we have
                            a Widget class (say), we will make its interface available as an ABC,
                            and then every module that needs to use a Widget class implement the
                            interface. This is not scaleable - as N different classes (in different
                            library modules) that delegate to the Widget class will have to write N
                            implementations for the Widget class. The duplicity of effort that
                            entails (not to mention the increased scope for errors/nightmare code
                            maintenance etc) is so ridiculous that I have to assume that I have
                            misunderstood you - please clarify.

                            Comment

                            • Ben Voigt [C++ MVP]

                              #15
                              Re: exporting a C++ object in a DLL


                              "Grey Alien" <grey@andromeda .comwrote in message
                              news:1M-dnYGHAO2cEBHbRV nytgA@bt.com...
                              >
                              >
                              Ben Voigt [C++ MVP] wrote:
                              >>
                              >
                              >>However, as a matter of interest, if only the interface is specified
                              >>(via pure virtuals in a header) - surely, it means that EACH child class
                              >>will have to implement the same functionality allover again. The idea
                              >>for exporting classes was for code reuse - which you seem to be losing,
                              >>using the Pimpl pattern you describe. Am I missing something?
                              >>
                              >>
                              >Yup. The interface can be implemented in a base class which provides the
                              >implementation , and each derived (or child if you prefer) class inherits.
                              >Only the interface cannot have any implementation, but it can participate
                              >in a full hierarchy.
                              >
                              But if the interface is implemented in a base class, then that base class
                              needs to be exported, so that its derived classes can correctly link to
                              the approriate compilation units - so we end up in the same situation, i.e
                              having to export the (base) class.
                              >
                              Unless I am misunderstandin g you, your approach ensures that if we have a
                              Widget class (say), we will make its interface available as an ABC, and
                              then every module that needs to use a Widget class implement the
                              interface. This is not scaleable - as N different classes (in different
                              library modules) that delegate to the Widget class will have to write N
                              implementations for the Widget class. The duplicity of effort that entails
                              (not to mention the increased scope for errors/nightmare code maintenance
                              etc) is so ridiculous that I have to assume that I have misunderstood
                              you - please clarify.
                              The module that you think you want to dllexport a class from...

                              Instead you declare an interface (class with only pure virtual functions) in
                              its public header file. Include this from the clients. Since the members
                              are pure virtual, the header has the complete definition and no
                              declspec(dllexp ort) is needed.

                              Now in that module providing the class, you create a declspec(dllexp ort)
                              extern "C" function (or several) for creating instances, called a factory
                              method. The instances are of a class that implements the interface. If you
                              want polymorphism between multiple implementations , multiple classes can
                              provide an implementation by inheriting the interface. These multiple
                              classes can each implement the interface independently, or they can inherit
                              from each other to share an interface.

                              Comment

                              Working...