[Qt-interest] Q_OBJECT in DLL - Release build warnings

Catalin Roman katalin.roman at gmail.com
Mon Feb 8 13:54:37 CET 2010


Hello again,
Unfortunately with the same problem, but now it appears in both
Debug/Release build modes. As I stated earlier, all my defines are in place:

in foo.pro:
DEFINES += FOO_LIBRARY

in foo_global.h:
#if defined(FOO_LIBRARY)
#  define FOOSHARED_EXPORT Q_DECL_EXPORT
#else
#  define FOOSHARED_EXPORT Q_DECL_IMPORT
#endif

in foo.h:
class FOOSHARED_EXPORT myClass : public QObject{
Q_OBJECT;
public:
...
}

Is it possible that I'm missing some other Qt Creator setting? If so, which
one?

Also, I'm thinking that if it were a problem with some missing defines, I
should have received the warnings for all the public functions inside my
class, and not only for those functions declared by the Q_OBJECT macro.
Am I right to suspect the moc compiler for generating these warnings (the
warnings appear in the moc_foo.cpp), since the warnings dissappear when I
explicitly declare the needed inherited functions form QObject ?


On Mon, Feb 8, 2010 at 2:06 PM, Catalin Roman <katalin.roman at gmail.com>wrote:

> Thanks a lot for you quick reply.
> Funny thing is that when I followed your suggestions I realized that all
> the defines were already in place ! And, of course, the warnings were gone
> :). Anyhow, you gave me a very good hint to export only the necessary
> functions. Thanks again.
>
>
> On Mon, Feb 8, 2010 at 12:55 PM, <Oliver.Knoll at comit.ch> wrote:
>
>> Catalin Roman wrote on Monday, February 08, 2010 10:50 AM:
>>
>> > This is my first post, so please let me know gently if this is the
>> > wrong place to seek answers
>>
>> Hi there and welcome :)
>>
>> >  to my following problem.
>> > I'm building a DLL using Qt 4.6 and Qt Creator 1.3.0. The main class
>> > of the DLL has the Q_OBJECT macro declared in the .h file because I'm
>> > using signals/slots. When I build in Release mode,
>>
>> So I read it implicitly that it works in debug mode, right?
>>
>> > I get 4 warnings
>> > concerning staticMetaObject, metaObject(), qt_metacast() and
>> > qt_metacall() saying "redeclared without dllimport attribute after
>> > being referenced with dll linkage/previous dllimport ignored".
>>
>> These "redeclared without dllimport" warnings are typical for wrong "DLL
>> export/import" declarations, typically due to a missing or wrong DEFINE in
>> the project settings.
>>
>> So without knowing the exact problem in your case I am giving you a rather
>> generic answer how it /should/ work:
>>
>> First, for each DLL project, I define a header such as (for library Foo):
>>
>> // FooDLL.h
>> #ifndef __FOO_DLL_H_
>> #define __FOO_DLL_H_
>>
>> #include <QtGlobal>
>>
>> #ifdef FOO_EXPORT
>> # define FOO_API Q_DECL_EXPORT
>> #else
>> # define FOO_API Q_DECL_IMPORT
>> #endif
>>
>> #endif // __FOO_DLL_H_
>>
>> Note the usage of the Qt Q_DECL_EXPORT / Q_DECL_IMPORT macros: they expand
>> to the __declspec(dllimport/export) thing on Windows (using the Visual
>> Studio compiler) and to "nothing" everywhere else (IIRC). So they come quite
>> handy here.
>>
>>
>> Next, let's assume we want to export the *whole* following class from our
>> Foo library:
>>
>> #include <QtCore/QObject>
>> #include "FooDLL.h"
>> ...
>>
>> class FOO_API Foo : public QObject {
>>  Q_OBJECT
>> public:
>>  Foo();
>>  virtual ~Foo();
>>
>>  void doFoo();
>>  void doBar();
>>  ...
>> signals:
>>  void signalFoo();
>>  ...
>> private:
>>  void doSomething();
>> };
>>
>>
>> Now the crucial thing here is off course that you DEFINE FOO_EXPORT within
>> your "Foo" project, but that you DON'T DEFINE it for every other project
>> (that is using the Foo library). This way the FOO_API will become the proper
>> Q_DECL_EXPORT (when building the library) or Q_DECL_IMPORT respective (when
>> "importing" / using the library from any other project).
>>
>> Typically this is done in your Foo.pro like:
>>
>> DEFINE += FOO_EXPORT
>>
>> (or in Visual Studio, right-click on your project -> Properties -> C/C++
>> -> Preprocessor and define it there for BOTH DEBUG and RELEASE
>> configurations!)
>>
>> If however - my preferred way - you only want to export /certain/ methods,
>> this should (and does, in my case) also work:
>>
>> class Foo : public QObject {
>>  Q_OBJECT
>> public:
>>  FOO_API Foo();
>>  FOO_API virtual ~Foo();
>>
>>  FOO_API void doFoo();
>>  void doBar();
>>  ...
>> signals:
>>  void signalFoo();
>>  ...
>> };
>>
>>
>> That is, only the (public) methods Foo(), ~Foo() and doFoo() are exported
>> and hence can be called from another library/*.exe. In the above example
>> doBar() however can *not* be called. Well, technically your code would
>> compile if you would call doBar() from any other place than the Foo library,
>> but you would get a linker error! This gives you an additional "package
>> visibility" level :) And since you are only exporting the really needed
>> methods this also results in a *slightly* smaller DLL ;)
>>
>>
>> To answer your concrete question again, I assume that you either
>>
>> - Did not properly export your class or
>> - You forgot to DEFINE the corresponding "EXPORT" value in your release
>> configuration
>>
>>
>> Cheers, Oliver
>> --
>> Oliver Knoll
>> Dipl. Informatik-Ing. ETH
>> COMIT AG - ++41 79 520 95 22
>> _______________________________________________
>> Qt-interest mailing list
>> Qt-interest at trolltech.com
>> http://lists.trolltech.com/mailman/listinfo/qt-interest
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20100208/e19ed387/attachment.html 


More information about the Qt-interest-old mailing list