Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Linking against own linbrary



  • Good morning,
    looks like I need some help from the Community again. I got puzzled reading the documentation and obviously my background knowledge is not enough here. For the record: I am using Qt 14.0 (I can't download 14.1 due to a sloppy mirror in UK and don't have time to play around with switching mirrors which is not trivial).

    I have a multidir project, which so far compiles and works nicely, every part of it. At some point it became clear that either I can include same class in two different subprojects or move them to separate subprojects as libraries. To maximise flexibility for the future (project will be rather continues development for the next two or three years) improvements I've decided for the latter. Never written a library before, so I went through documentation on the subject - libraries compile well, target files are where I expected them. Here is a pro file of one of the libs:

    QT -= gui
    QT += network
    TEMPLATE = lib
    DEFINES += ZLOGGER_LIBRARY
    CONFIG += c++14 create_prl link_prl
    DEFINES += QT_DEPRECATED_WARNINGS
    SOURCES += \
        zlogger.cpp
    HEADERS += \
        ZLogger_global.h \
        zlogger.h
    target.path = $PWD/../shared
    INSTALLS += target
    DISTFILES += \
        COPYING \
        README.md \
        doc/Doxyfile
    DESTDIR = ../shared/
    

    File ZLogger_global.h is a generic file with #ifdef macros created by Qt Creator:

    #ifndef ZLOGGER_GLOBAL_H
    #define ZLOGGER_GLOBAL_H
    
    #include <QtCore/qglobal.h>
    
    #if defined(ZLOGGER_LIBRARY)
    #  define ZLOGGER_EXPORT Q_DECL_EXPORT
    #else
    #  define ZLOGGER_EXPORT Q_DECL_IMPORT
    #endif
    
    #endif // ZLOGGER_GLOBAL_H
    

    File logger.h (stripped of comments, just public part that I wish to have exported):

    class ZLOGGER_EXPORT ZLogger:public QObject
    {
      Q_OBJECT
    
    public:
      enum ZLogStatus {
        ZlogOK = 0,
        ZLogWriteError = 1,
        ZLogOpenError = 2
      };
      enum ZLogLevel:qint32 {
        All = 0,
        Informative = 1,
        Warning = 2,
        Error = 3,
        Info = 4
      };
      ZLogger(QObject *parent = nullptr);
      ~ZLogger();
      void Log(const QString sender,const QVariant message,const ZLogLevel level = All);
      void setSyncInterval();
      void setNetworkURL(const QString url);
      ZLogStatus lastError();
      QString lastErrorText();
    (...)
    }
    

    Now what I can't get working, obviously, is inclusion in the client (again, class above worked just fine when included directly so I messed up the export, the import of both).
    According to the documentation cited above, I include ZLogger_global.h (which makes sense). Then goes the line:

    class ZLOGGER_EXPORT ZLogger;
    

    But when a client class, which has a member

    ZLogger *logger;
    

    tries to use one of the methods later in the code:

    logger->Log(objectName(),message);
    

    that line is being highlighted with the error message: "member access into incomplete class ZLogger".

    The question: how do I properly export/import that kind of a class? I read the docs, did some googling but it all is very... inconclusive.

    Thanks in advance for any help, as always.
    Artur


  • Lifetime Qt Champion

    @artwaw Don't you #include logger.h?

    Regards



  • @aha_1980 I don't, in fact. Impression that I've got from the documentation was that I should not. From your question I guess that I should include both?
    If so - do I even need to declare the ZLogger class in the client with the ZLOGGER_EXPORT macro?


  • Lifetime Qt Champion

    @artwaw These macros are only needed on Windows, and IIRC with MSVC, which does not export symbols by default.

    E.g. on Linux, they are indeed not needed.



  • @aha_1980 Target for the project is macOS, Windows 10 and maybe Debian (but no decision made on that yet). For Windows I use mingw as I am not a fan of MSVC.
    So, to clarify, I should just skip the macros, include the headers in the source code, link library in the .pro file as any other I use and that's it?


  • Lifetime Qt Champion

    @artwaw Why don't you just try it? :)

    I guess the "Qt correct" way would be to #include zlogger_global.h in zlogger.h and to define the macro ZLOGGER_EXPORT when you compile the library (but not when you use them from your app!).

    But you may not need all that if you don't use MSVC.

    Regads



  • @aha_1980 I will try then - I prefer to ask before I do something stupid ;)
    The "Qt correct" way is already done with regards to library compilation, I'll just leave it be - it doesn't hurt and I don't know what future might bring along, someone might wish to use it with msvc (although that would be over my dead body...).
    I am marking this as solved as I think I can get things working from here.

    Thank you for clarifications and advice, as always highly appreciated.


Log in to reply