Re: What am I missing? Unresolved externals
src/corelib/global/qglobal.h:# define Q_DECL_EXPORT __declspec(dllexport)
Code:
#ifndef Q_DECL_EXPORT
# ifdef Q_OS_WIN
# define Q_DECL_EXPORT __declspec(dllexport)
# elif defined(QT_VISIBILITY_AVAILABLE)
# define Q_DECL_EXPORT __attribute__((visibility("default")))
# endif
# ifndef Q_DECL_EXPORT
# define Q_DECL_EXPORT
# endif
#endif
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by wysota
src/corelib/global/qglobal.h:# define Q_DECL_EXPORT __declspec(dllexport)
Code:
#ifndef Q_DECL_EXPORT
# ifdef Q_OS_WIN
# define Q_DECL_EXPORT __declspec(dllexport)
# elif defined(QT_VISIBILITY_AVAILABLE)
# define Q_DECL_EXPORT __attribute__((visibility("default")))
# endif
# ifndef Q_DECL_EXPORT
# define Q_DECL_EXPORT
# endif
#endif
And where's __declspec(dllimport)?
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by jacek
And where's __declspec(dllimport)?
I didn't say there is.
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by wysota
I didn't say there is.
But in this case it's useless.
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by jacek
But in this case it's useless.
Not quite...
You can always redefine that macro (which doesn't change the fact that a need for such thing at all is just stupid) before including headers.
Code:
#ifdef Q_OS_WIN
# ifdef Q_DECL_EXPORT
# undef Q_DECL_EXPORT
# endif
# define Q_DECL_EXPORT __declspec(dllimport)
#endif
#include "somefile.h"
#undef Q_DECL_EXPORT
Anyway my point was that Qt helps a little with defining those macros. It helps source code to be more portable. I didn't say it (unfortunately) releases the user from knowing that OS-dependent little magic tricks.
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by wysota
Not quite...
You can always redefine that macro (which doesn't change the fact that a need for such thing at all is just stupid) before including headers.
[...]
Anyway my point was that Qt helps a little with defining those macros. It helps source code to be more portable.
So Qt provides an undocumented macro that you must redefine to able to use it. Well... I wouldn't call it helpfull. ;)
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by jacek
Probably nowhere, it's specific only to windows DLLs --- normal systems doesn't require this.
"normal systems". So I can make plugins for Windows which arn't dlls? I just want plugins to work on Windows - I don't care how!
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by Paul Drummond
"normal systems". So I can make plugins for Windows which arn't dlls? I just want plugins to work on Windows - I don't care how!
What Jacek meant was that well written systems don't require those macros, while Windows does ;)
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by jacek
Where? ;)
I believe it's Q_EXPORT (or at least it was in Qt3).
Then you define -D QT_DLL or -D QT_NODLL depending on whether you are linking with a dll or a static library.
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by Chicken Blood Machine
I believe it's Q_EXPORT (or at least it was in Qt3).
Yes it was in Qt3, but is there something similar in Qt4?
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by jacek
Yes it was in Qt3, but is there something similar in Qt4?
I've just checked my ported Qt4 code and I seem to be using Q_DECL_EXPORT
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by Chicken Blood Machine
I've just checked my ported Qt4 code and I seem to be using Q_DECL_EXPORT
OK, so there is Q_DECL_EXPORT and Q_DECL_IMPORT which are set correctly. The only missing thing is a single macro which will be set to Q_DECL_EXPORT or Q_DECL_IMPORT depending on whether you build DLL or application that uses it.
Something like this:
Code:
#ifdef QT_DLL
# define EXPORT Q_DECL_EXPORT
#else
# define EXPORT Q_DECL_IMPORT
#endif
Re: What am I missing? Unresolved externals
Correct me if i'm wrong - but as far as i can tell, Q_DECL_EXPORT and Q_DECL_IMPORT are the macros used by Qt when building a plugin. From an aesthetic viewpoint you should use your own when building an off-the-shelf dynamic library.
If i want to build an dynamic library (let's call it mylib), i include the following header called MyLibDef.h in every class header file whose interface i want to be exported to the dll.
Code:
#ifndef MY_LIBDEF_H_
#define MY_LIBDEF_H_
#if defined(WIN32)
# ifdef MY_LIB_DLL
# define MY_LIB_DLLMAPPING __declspec(dllexport)
# else
# define MY_LIB_DLLMAPPING __declspec(dllimport)
# endif
#else
# define MY_LIB_DLLMAPPING
#endif
#endif
The class declarationt then looks like this:
Code:
class MY_LIB_DLLMAPPING Foo
: public QWidget...
I then add the -D MY_LIB_DLL to the compiler flags when i compile the dll. When i use the headers in some app that links the library the MY_LIB_DLL is not set by default ;) and everything is fine.
Cutting-and-pasting-and-replacing MY_LIB with something other takes approximately 30 seconds - IMHO this ain't that much ;)
Regarding the WIN32 symbol: I don't use qmake so it might be that WIN32 will not work but you can replace it with the symbol Q_OS_WIN spotted in one of the posts above.
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by orb9
Correct me if i'm wrong - but as far as i can tell, Q_DECL_EXPORT and Q_DECL_IMPORT are the macros used by Qt when building a plugin. From an aesthetic viewpoint you should use your own when building an off-the-shelf dynamic library.
If i want to build an dynamic library (let's call it mylib), i include the following header called MyLibDef.h in every class header file whose interface i want to be exported to the dll.
Code:
#ifndef MY_LIBDEF_H_
#define MY_LIBDEF_H_
#if defined(WIN32)
# ifdef MY_LIB_DLL
# define MY_LIB_DLLMAPPING __declspec(dllexport)
# else
# define MY_LIB_DLLMAPPING __declspec(dllimport)
# endif
#else
# define MY_LIB_DLLMAPPING
#endif
#endif
The class declarationt then looks like this:
Code:
class MY_LIB_DLLMAPPING Foo
: public QWidget...
I then add the -D MY_LIB_DLL to the compiler flags when i compile the dll. When i use the headers in some app that links the library the MY_LIB_DLL is not set by default ;) and everything is fine.
Cutting-and-pasting-and-replacing MY_LIB with something other takes approximately 30 seconds - IMHO this ain't that much ;)
Regarding the WIN32 symbol: I don't use qmake so it might be that WIN32 will not work but you can replace it with the symbol Q_OS_WIN spotted in one of the posts above.
I agree completely. This should probably be put in an FAQ for people coming over from the UNIX world.
I'm currently working with Windows dlls at work and I have to say I hate the crappy implementation that MS has. On unix, you generally don't even need to know whether you are linking with a shared library or an archive library and you don't need any 'clever' macros when writing the interface for a library either. OK - rant over - don't bother responding to this :mad:
Re: What am I missing? Unresolved externals
Ok, I made some progress:
When I tried to build the mySQL plugin it just did not work. The n I rebuilt my whole Qt from source (not using qt-win-commercial-4.1.0-vs2003.exe) and it magically worked.
For the moment I use this in my PRO file and it works:
Code:
#Settings:
QT += qt3support xml sql
QT -= gui
#CONFIG += dll
CONFIG += staticlib
#DEFINES += BUILD_DLL
#DLLDESTDIR = ../xpaf
DESTDIR = ../xpaf
TEMPLATE = lib
#Settings end
I'll revert back to DLLs soon and see how it goes.
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by Chicken Blood Machine
I'm currently working with Windows dlls at work and I have to say I hate the crappy implementation that MS has. On unix, you generally don't even need to know whether you are linking with a shared library or an archive library and you don't need any 'clever' macros when writing the interface for a library either. OK - rant over - don't bother responding to this :mad:
I don't like the dark side, too... but this time part of their stuff isn't that bad.
The __declspec(dllexport) directive tells the compiler to explicitly export the class from the DSO. This enables tuning of a DSO interface, which results in smaller compiled code, improved loading time, etc. This feature (even better ;) is available in >=gcc-3.4, too. See
http://gcc.gnu.org/wiki/Visibility
for more infos.
Re: What am I missing? Unresolved externals - SOLVED
One of my problems:
My MS Visual Studio project files got overwritten by the Qt VS integration plugin making that the librarian skips my moc_*.obj files as the output directory changed.
Thanks to this thread:
http://www.qtcentre.org/forum/showthread.php?t=450
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by orb9
I don't like the dark side, too... but this time part of their stuff isn't that bad.
The __declspec(dllexport) directive tells the compiler to explicitly export the class from the DSO. This enables tuning of a DSO interface, which results in smaller compiled code, improved loading time, etc. This feature (even better ;) is available in >=gcc-3.4, too. See
http://gcc.gnu.org/wiki/Visibility
for more infos.
Hmm, I wasn't aware of that. You learn something new every day! Thanks for the info.
Re: What am I missing? Unresolved externals
I'm sorry, but can someone please explain to me why all this isn't explained in the Qt documentation? When reading about plugins and QLibrary, the Troll's should state if the code won't work on a particular platform. If I developed a plugin in Linux I would expect it to work on all supported platforms WITHOUT CODE CHANGES. I would accept configuration and compilation issues, but this is a code modification which isn't acceptable IMO.
Re: What am I missing? Unresolved externals
Quote:
Originally Posted by Paul Drummond
I'm sorry, but can someone please explain to me why all this isn't explained in the Qt documentation?
It isn't?
Quote:
On Windows you must also explicitly export the function from the DLL using the __declspec(dllexport) compiler directive, for example:
extern "C" MY_EXPORT int avg(int a, int b)
{
return (a + b) / 2;
}
with MY_EXPORT defined as
#ifdef Q_WS_WIN
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT
#endif
Well... one might expect that this should be placed in different parts of the documentation too, but you can't say it isn't explained ;)
Anyway, the Trolls are responsible for the documentation, so you should ask them, not users of this forum.