CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    __declspec(dllexport)

    While browsing through somebody's code the other day I came across this C++ class (it's not the full code - just enough for illustration purposes)

    Code:
    class GLIBMM_API Object : virtual public ObjectBase
    {
    protected:
      Object(); //For use by C++-only sub-types.
      explicit Object(const Glib::ConstructParams& construct_params);
      explicit Object(GObject* castitem);
      virtual ~Object(); //It should only be deleted by the callback.
    
    public:
      //static RefPtr<Object> create(); //You must re-implement this in each derived class.
    
      //GObject* gobj_copy(); //Give a ref-ed copy to someone. Use for direct struct access.
    
      // convenience functions
      //template <class T>
      //void set_data_typed(const Quark& quark, const T& data)
      //  { set_data(quark, new T(data), delete_typed<T>); }
    
      //template <class T>
      //T& get_data_typed(const QueryQuark& quark)
      //  { return *static_cast<T*>(get_data(quark)); }
    
    private:
      friend class Glib::Object_Class;
      static CppClassType object_class_;
    
      // noncopyable
      Object(const Object&);
      Object& operator=(const Object&);
    };
    Notice that it uses GLIBMM_API. When building the library as a DLL, GLIBMM_API is defined as __declspec(dllexport) whereas it gets re-defined to __declspec(dllimport) when building other apps that use the DLL. I assume the intention is that all exportable classes will get derived from class Object.

    Whenever I've done something similar in my own code I usually ended up laboriously adding my own WHATEVER_API statements all over the place. It never occurred to me to have a simple base class and then derive all the others from it. I suppose it's a bit lazy but does anyone know if this technique works - i.e. would the derived classes have __declspec(dllexport) correctly defined, so their functions would all be visible (i.e. exported) from the DLL?

    I could imagine this being a useful technique for dealing with 3rd party libraries which weren't originally intended to get built as Windows DLLs.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  2. #2
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: __declspec(dllexport)

    You aren't entirely right on your assumptions.
    The technique isn't new or unique, it's used throughout MFC as well. And is also applied if you make MFC extention DLL's.

    When building the DLL, you have a define that equates to __declspec(dllexport) and that allows you to export all the functions you want.
    It's logical that each function that is being exported, can also be imported, so when including the same header from code that will use the dll, you have that same define equate to __declspec(dllimport). it's an elegant solution to a annoying problem, even though C++ purists will advocate against any and all use of macro's.. That's all fine and dandy until y ou have to write actual code that needs to interface with real operating systems

    doing this at the class level, simply means "export (or import) all member functions of this class". Fine if you wanted to export everything but it can cause some overhead if you don't want all member functions to be exported. Even in that case I see it used often simply "because it's easier than doing it one function at a time"

    Note that the __declspec() does NOT automatically extend to derived classes. if you want the derived class to be exported also, you'll have to add a __declspec(dllexport) (or the macro) to the derived class definition as well.

  3. #3
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: __declspec(dllexport)

    Quote Originally Posted by OReubens View Post
    doing this at the class level, simply means "export (or import) all member functions of this class". Fine if you wanted to export everything but it can cause some overhead if you don't want all member functions to be exported. Even in that case I see it used often simply "because it's easier than doing it one function at a time"

    Note that the __declspec() does NOT automatically extend to derived classes. if you want the derived class to be exported also, you'll have to add a __declspec(dllexport) (or the macro) to the derived class definition as well.
    Thanks, it was that last bit that I was unsure about. If __declspec() automatically extended to derived classes, I feel sure I'd have heard about it by now!

    So having one common base class isn't a quick route to making all derived class symbols exportable? The technique was buried deep in the code somewhere so I guess it was something that the programmer tried at some point, but then probably abandoned.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  4. #4
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: __declspec(dllexport)

    Quote Originally Posted by John E View Post
    So having one common base class isn't a quick route to making all derived class symbols exportable? The technique was buried deep in the code somewhere so I guess it was something that the programmer tried at some point, but then probably abandoned.
    I believe you just fictionalize the original intentions. Typically full class export is used to let dll hosted classes be created outside the dll, just like that, as full class export is the only way to export all class constructors/destructors, explicit or implicit ones.
    Best regards,
    Igor

  5. #5
    Join Date
    Nov 2003
    Posts
    1,902

    Re: __declspec(dllexport)

    >> So having one common base class isn't a quick route to making all derived class symbols exportable?
    No, but you can achieve something similar without using __declspec(). By sticking with virtual interfaces you can use the object's v-table as in "implicit exporter". Then the DLL only needs to export factories that return objects that support these interfaces - like "bool CreateSomeObject(Obect **pp)". Basically COM without the COM.

    gg

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured