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. C++ DLLs as plugins in Qt
Forum Updated to NodeBB v4.3 + New Features

C++ DLLs as plugins in Qt

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 2 Posters 583 Views 1 Watching
  • 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.
  • K Offline
    K Offline
    KagonKhan
    wrote on last edited by
    #1

    What I look for is implementing into a Qt app, a plugin system. The plugin would be a DLL that accepts an array and returns some values (similarity metrics, where each DLL is a different metric)
    I know that Qt has a plugin interface, but ideally I would like the plugins to be creatable without the framework itself.

    What I have so far is a working C++ code that does exactly that

    
    void load() {
    	WIN32_FIND_DATA fileData;
    
    	HANDLE fileHandle = FindFirstFile(R"(.\plugins\*.dll)", &fileData);
    
    	if (fileHandle == (void*)ERROR_INVALID_HANDLE ||
    		fileHandle == (void*)ERROR_FILE_NOT_FOUND) {
    		return;
    	}
    
    	do {
    		HINSTANCE temp = LoadLibrary((R"(.\plugins\)" + std::string(fileData.cFileName)).c_str());
    
    		if (!temp) {
    			// error //std::cerr << "Couldn't load: " << fileData.cFileName << "!\n";
    			continue;
    		}
    
    		typedef std::unique_ptr<Base>(__cdecl* ObjProc)(void);
    		typedef std::string(__cdecl* NameProc)(void);
    
    		ObjProc objFunc = (ObjProc)GetProcAddress(temp, "getObj");
    		NameProc nameFunc = (NameProc)GetProcAddress(temp, "getName");
    
    		std::unique_ptr<Base> obj = objFunc();
    		std::cout << "\t" << obj->calc(5) << std::endl;
    
    	} while (FindNextFile(fileHandle, &fileData));
    }
    

    I tried translating it as follows:

    
    void ImageMetrics::loadPlugins()
    {
        qDebug ("PLUGIN1") ;
    
        WIN32_FIND_DATA fileData;
        HANDLE fileHandle = FindFirstFile(L"(.\plugins\*.dll)", &fileData);
    
        if (fileHandle == (void*)ERROR_INVALID_HANDLE || fileHandle == (void*)ERROR_FILE_NOT_FOUND) {
            return;
        }
        static int counter = 0;
        qDebug ("PLUGIN2") ;
        do {
            HINSTANCE temp = LoadLibrary( std::wstring(L"(.\plugins\)" + std::wstring(fileData.cFileName)).c_str());
            std::string test = ws2s(std::wstring(L"(.\plugins\)" + std::wstring(fileData.cFileName)).c_str());
            auto test1 =QString::fromStdString(test);
    
            qDebug() << test1;
            qDebug() << counter++;
    
            if (!temp) {
                qDebug("Couldn't load: !\n");
                continue;
            }
    
            modules.push_back(temp);
    
            typedef std::unique_ptr<Base>(__cdecl* ObjProc)(void);
            typedef std::string(__cdecl* NameProc)(void);
    
            ObjProc objFunc = (ObjProc)GetProcAddress(temp, "getObj");
            NameProc nameFunc = (NameProc)GetProcAddress(temp, "getName");
    
            qDebug ("PLUGIN3") ;
    
            std::unique_ptr<Base> obj = objFunc();
            m_Plugins.emplace_back(std::move(obj));
    
        } while (FindNextFile(fileHandle, &fileData));
    }
    

    I tried pasting a Plugin folder with DLLs in different spaces, but cant get the software to read the data. I'm a complete newbie with Qt. Any help appreciated.

    1 Reply Last reply
    0
    • K Offline
      K Offline
      KagonKhan
      wrote on last edited by KagonKhan
      #6

      Okay, got a working (WINDOWS) solution, probably not perfect but oh well.

      .h file

      typedef double(*CalcFunction)(double);
      std::vector<CalcFunction> m_Plugins;
      
      void loadPlugins();
      

      .cpp file

      void ImageMetrics::loadPlugins()
      {
          m_Plugins.clear();
      
          QDir directory(QDir::currentPath());
          directory.cd(QString("Plugins"));
      
          auto path = QDir::cleanPath(directory.path());
          SetDllDirectoryA(path.toStdString().c_str());
      
          QStringList plugins = directory.entryList(QStringList() << "*.dll", QDir::Files);
          foreach(QString plugin, plugins) {
              QLibrary lib(plugin);
      
              CalcFunction calc = (CalcFunction)lib.resolve("calc");
      
              if (calc){
                  m_Plugins.push_back(calc);
                 qDebug() << m_Plugins.back()(25);
              }
              else
                  qDebug() << lib.errorString();
          }
      }
      

      PSA if other get stuck and find their way here:

      • Make sure your DLLs match your Qt Creator architecture (I was using 32 bit DLLs with 64 bit Creator.
      • Your DLL functions have to be wrapped in extern "C" __declspec(dllexport) (I didn't have the extern part)
      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi and welcome to devnet,

        Qt already provides all you need to implement plugins for your application in a cross platform fashion.

        See the Plugins How To chapter in the Qt documentation.

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

        1 Reply Last reply
        1
        • K Offline
          K Offline
          KagonKhan
          wrote on last edited by
          #3

          But to create new Plugins I would need Qt framework, to compile them. Is that not the case? (that's how I read it)

          If that is the case, I am looking for a solution that allows development of plugins in basic C/C++ environment without the need of Qt

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

            If I may, you want to add plugins to a Qt application but not use Qt's facilities to do that which is a bit counter-productive.

            What I would recommend is to implement the core functionalities that you want in "pure c++" in a library and then use that library to build a plugin that you can use with QPluginLoader. That way you can keep the two things separated while taking advantage of the system.

            As for your location issue, where exactly did you put your plugin folder ?

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

            1 Reply Last reply
            1
            • K Offline
              K Offline
              KagonKhan
              wrote on last edited by
              #5

              Yea, ideally I would use plugin loader, but it's not optimal, as it forces (afaik) people that would wish to write more DLLs to get the framework.

              As for your suggestion, if that allows people to write plugins without compiling Qt specific code -> could you point me, where I could read up on such a procedure? This is all very new territory to me.

              Lastly about the folder; I just copy pasted the folder in the main app directory, app/build directory, app/build/debug directory

              1 Reply Last reply
              0
              • K Offline
                K Offline
                KagonKhan
                wrote on last edited by KagonKhan
                #6

                Okay, got a working (WINDOWS) solution, probably not perfect but oh well.

                .h file

                typedef double(*CalcFunction)(double);
                std::vector<CalcFunction> m_Plugins;
                
                void loadPlugins();
                

                .cpp file

                void ImageMetrics::loadPlugins()
                {
                    m_Plugins.clear();
                
                    QDir directory(QDir::currentPath());
                    directory.cd(QString("Plugins"));
                
                    auto path = QDir::cleanPath(directory.path());
                    SetDllDirectoryA(path.toStdString().c_str());
                
                    QStringList plugins = directory.entryList(QStringList() << "*.dll", QDir::Files);
                    foreach(QString plugin, plugins) {
                        QLibrary lib(plugin);
                
                        CalcFunction calc = (CalcFunction)lib.resolve("calc");
                
                        if (calc){
                            m_Plugins.push_back(calc);
                           qDebug() << m_Plugins.back()(25);
                        }
                        else
                            qDebug() << lib.errorString();
                    }
                }
                

                PSA if other get stuck and find their way here:

                • Make sure your DLLs match your Qt Creator architecture (I was using 32 bit DLLs with 64 bit Creator.
                • Your DLL functions have to be wrapped in extern "C" __declspec(dllexport) (I didn't have the extern part)
                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