Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QObject::connect signal not found in dll with Pointer to Member Function

QObject::connect signal not found in dll with Pointer to Member Function

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 4 Posters 1.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    madmiraal
    wrote on last edited by
    #1

    This problem is specific to a library compiled as a shared library on Windows i.e. a dll when trying to connect to a signal in an object in the library using a pointer to the member signal function.

    When trying to connect to a signal in a dll using a PointerToMemberFunction signal QObject::connect function, it fails with a runtime error of QObject::connect signal not found in <Class name>.
    The following sample code can be used to demonstrate the problem:

    #ifndef LIBRARY_H
    #define LIBRARY_H
    #include <QObject>
    class Library : public QObject
    {
    Q_OBJECT
    public:
        void emitSignal(){ emit signal(); }
    signals:
        void signal();
    };
    #endif // LIBRARY_H
    
    #include "library.h"
    #include <iostream>
    int main()
    {
        Library library;
        QObject::connect(&library, &Library::signal, []()
        {
            std::cout << "Caught signal!" << std::endl;
        });
        library.emitSignal();
    }
    

    The above code compiles and works correctly on Linux and Mac with the library compiled as a shared library or a static library. It also compiles and works on Windows when the library is compiled as a static library. It compiles, but fails to connect on Windows when the library is compiled as a shared library i.e. a dll.

    In addition to the above problem description I can confirm the following:

    1. It works if the above code is changed to use one of the const char *signal QObject::connect functions. However, there are two reasons this is not a satisfactory solution: a) There are no Functor options with the const char *signal QObject::connect functions. b) Using PointerToMemberFunction signal options should provide compile time errors if the signal does not exist. Ironically, this is exactly the opposite of the problem being experienced.

    2. The code is failing inside the moc code generated for the library object.

    void Library::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
    {
        if (_c == QMetaObject::InvokeMetaMethod) {
            auto *_t = static_cast<Library *>(_o);
            Q_UNUSED(_t)
            switch (_id) {
            case 0: _t->signal(); break;
            default: ;
            }
        } else if (_c == QMetaObject::IndexOfMethod) {
            int *result = reinterpret_cast<int *>(_a[0]);
            {
                using _t = void (Library::*)();
                _t left = *reinterpret_cast<_t *>(_a[1]);
                _t right = static_cast<_t>(&Library::signal);
                if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&Library::signal)) {
                    *result = 0;
                    return;
                }
            }
        }
        Q_UNUSED(_a);
    }
    

    I have added the two lines to visualise the two sides being compared in the following line:

                _t left = *reinterpret_cast<_t *>(_a[1]);
                _t right = static_cast<_t>(&Library::signal);
    

    When debugging the Windows dll version, both left and right point to the same function, but left is pointing to code inside the application and right is pointing to code inside the library. (In all other versions, both left and right point to the same location in memory: inside the library.)

    1. There is nothing wrong with the pointer to the function in the application, as it can be used to call the signal function: it will call the moc generated code inside the dll.

    Any ideas?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      You are not exporting your symbols correctly. See the Creating Shared Libraries chapter in Qt's documentation.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      Q 1 Reply Last reply
      5
      • SGaistS SGaist

        Hi and welcome to devnet,

        You are not exporting your symbols correctly. See the Creating Shared Libraries chapter in Qt's documentation.

        Q Offline
        Q Offline
        QtTester
        wrote on last edited by
        #3
        This post is deleted!
        1 Reply Last reply
        0
        • S Offline
          S Offline
          seyed
          wrote on last edited by
          #4

          In my case, I have common source that separated as a .pri project.
          I included common.pri in my library named lib1 with pimpl idiom.
          Also, I did same in my application which uses lib1.
          This results to compile without any error or problem but same runtime error occurred at runtime.

          QObject::connect signal not found in <class name>
          
          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved