[Qt-interest] doubt regarding creation of shared libs in QT

Oliver.Knoll at comit.ch Oliver.Knoll at comit.ch
Fri May 7 17:22:40 CEST 2010


Mandeep Sandhu wrote on Friday, May 07, 2010 3:44 PM:

> > ...
> My library is a Linux only lib.

Then in theory you should not need to worry, since by default gcc exports all symbols from a shared library! (I think there *are* options how you can control which symbols exactly are exported with gcc, but I am not familiar with those). But it is good practise to use the Q_DECL_[EXPORT|IMPORT] macros anyway, shoulld you ever want to convert your code to Windows ;)

Also I found the use of these macros pretty useful, it gives you another degree of "visibility", "package visibility" if you wish - IF you use these export macros on a per symbol basis, as in:

// this #ifdef block is typically put into a separate header - I usually call them of the form MyLibraryDLL.h
// Then ONLY for your MyLibrary project you define MY_LIBRARY_EXPORT (qmake: DEFINES += MY_LIBRARY_EXPORT),
// so MY_LIBRARY_API renders to the appropriate value
#ifdef MY_LIBRARY_EXPORT
#define MY_LIBRARY_API Q_DECL_EXPORT
#else
#define MY_LIBRARY_API Q_DECL_IMPORT
#endif

#include "MyLibraryDLL.h"
class MyLibraryClass {
public:
  // c'tor and d'tor exported
  MY_LIBRARY_API MyLibraryClass();
  MY_LIBRARY_API virtual ~MyLibraryClass();

  // this method can be called from a client which uses this library
  MY_LIBRARY_API virtual void doFoo();

  // this method CANNOT (should not) be called from a client which uses this library
  // it is like "package visible" only within this library - at least on
  // Windows you would get linker errors when trying to call and link
  // against this method! (Note that it IS public though)
  void doBar();
  ...
};

In theory you could also export the ENTIRE class:


class MY_LIBRARY_API MyLibraryClass {
  ...
};

On Windows this produces a SLIGHTLY bigger DLL (because also all protected and private symbols are exported, even though the later totally does not make any sense, off course - I might be wrong on the last point though).

But I prefer to have explicit control what exactly is exported, with the approach above, giving me this additional "package visibility" level, at the cost of slightly higher code maintenance costs (you have to "know" which methods you want to make accessible for the library user).

 
> Also, does this have to percolate down the inheritance hierarchy as
> well? 

As for you other question, inheritance: I don't think the "exporting" is inherited. The __declspec is compiler-specific and not part of the C++ language: it simply tells the compiler "when building the object file mark this symbol as exported, so it can be linked against from a client". It does not care about OO-hierarchies.

So:

#include "MyLibraryDLL.h"
#inlucde "MyLibraryClass.h"

class MyExtendedLibraryClass : public MyLibraryClass {
public:
  MY_LIBRARY_API MyExtendedLibraryClass();
  MY_LIBRARY_API virtual ~MyExtendedLibraryClass();

  // override and export again doFoo();
  MY_LIBRARY_API virtual void doFoo();

  // add a new method and export it
  MY_LIBRARY_API void doFooBar();
  ...
};

That is, I would explicitly export the symbols (again). Even if you had exported the entire base class (class MY_LIBRARY_API MyLibraryClass {...};) you would still need to export the "child/specialised classes" I guess.

But again, on Linux (and Mac OS X with gcc, too) Q_DECL_EXPORT renders to "nothing", AFAIK. So if you are programming some kernel module you can probably skip this entirely ;)

p.s. You can also have a look at the source code of http://www.pointshop3d.com if everything else fails, my old diploma work back in 2001 ;) It still uses Qt 3 (and was even developped with Qt 2, hence no Q_DECL_EXPORT, but __declspec(dllexport) directly), but the idea is totally the same.
  
Cheers, Oliver
-- 
Oliver Knoll
Dipl. Informatik-Ing. ETH
COMIT AG - ++41 79 520 95 22



More information about the Qt-interest-old mailing list