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. QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe
Forum Updated to NodeBB v4.3 + New Features

QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 4 Posters 8.0k Views 3 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.
  • MarKSM MarKS

    @kshegunov

    Thank you for this nice explanation.

    Well you should rather want them to share the same dlls, not the other way around, but anyway ...
    

    My bad. I meant that i have dlls with same names but belong to different SDK versions.

    I will try changing the working directory and see if it actually works.

    jsulmJ Offline
    jsulmJ Offline
    jsulm
    Lifetime Qt Champion
    wrote on last edited by
    #6

    @MarKS said in QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe:

    i have dlls with same names but belong to different SDK versions

    Why different SDK versions? This is asking for troubles (like mixing different Qt versions).

    https://forum.qt.io/topic/113070/qt-code-of-conduct

    MarKSM 1 Reply Last reply
    0
    • jsulmJ jsulm

      @MarKS said in QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe:

      i have dlls with same names but belong to different SDK versions

      Why different SDK versions? This is asking for troubles (like mixing different Qt versions).

      MarKSM Offline
      MarKSM Offline
      MarKS
      wrote on last edited by MarKS
      #7

      @jsulm I know but can't help it. They are proprietary sensor SDKs. That is why i chose to go plugins way. But it seems like changing the working directory is not helping either.

      I tried this:

      QFileInfo pluginPathInfo(path);
      
      qInfo() << "Current plugin dir:" << pluginPathInfo.dir().path();
      bool status = QDir::setCurrent(pluginPathInfo.dir().path());
      
      qInfo() << "Changed Current working dir:" << QDir::currentPath();
      

      I can see this changes the current working dir to my plugin directory but still the plugin fails to load.

      kshegunovK 1 Reply Last reply
      0
      • MarKSM MarKS

        @jsulm I know but can't help it. They are proprietary sensor SDKs. That is why i chose to go plugins way. But it seems like changing the working directory is not helping either.

        I tried this:

        QFileInfo pluginPathInfo(path);
        
        qInfo() << "Current plugin dir:" << pluginPathInfo.dir().path();
        bool status = QDir::setCurrent(pluginPathInfo.dir().path());
        
        qInfo() << "Changed Current working dir:" << QDir::currentPath();
        

        I can see this changes the current working dir to my plugin directory but still the plugin fails to load.

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by
        #8

        Okay, I guess I was wrong then. Anyway, could you dump the load-time dependencies from the plugin? On a related note, how do you link these libraries (what paths do you use) when building the actual plugin?

        Read and abide by the Qt Code of Conduct

        MarKSM 1 Reply Last reply
        0
        • kshegunovK kshegunov

          Okay, I guess I was wrong then. Anyway, could you dump the load-time dependencies from the plugin? On a related note, how do you link these libraries (what paths do you use) when building the actual plugin?

          MarKSM Offline
          MarKSM Offline
          MarKS
          wrote on last edited by MarKS
          #9

          @kshegunov I use CMake to configure my project. A sample plugin cmakelists.txt looks like this:

          # library name
          set(LIBRARY_NAME deviceA_plugin)
          
          add_library(${LIBRARY_NAME} 
                      SHARED 
                      ${Headers}
                      ${Sources}
                     )
                     
          # Link to libs
          target_link_libraries(${LIBRARY_NAME} 
                                PRIVATE
                                Boost::filesystem
                                Boost::date_time
                                Boost::regex
                                opencv_core
                                opencv_video
                                opencv_videoio
                                opencv_imgcodecs
                                opencv_imgproc
                                Qt5::Core                      
                                )
          
          target_include_directories(${LIBRARY_NAME}  
                                     PRIVATE 
                                     ${CMAKE_CURRENT_SOURCE_DIR}
                                     ${CMAKE_CURRENT_SOURCE_DIR}/..
                                     ${CMAKE_CURRENT_SOURCE_DIR}/../..
                                    )
                                    
          set(Used_OpenCV_Version "${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}")
          
          install(TARGETS ${LIBRARY_NAME}
                  RUNTIME
                  DESTINATION "plugins/DeviceA"
                  COMPONENT ${LIBRARY_NAME} 
                  )
          
          install(FILES
                  "${OpenCV_DIR}/bin/Release/opencv_videoio${Used_OpenCV_Version}.dll"
                  "${OpenCV_DIR}/bin/Release/opencv_video${Used_OpenCV_Version}.dll"
                  "${OpenCV_DIR}/bin/Release/opencv_imgcodecs${Used_OpenCV_Version}.dll"
                  "${OpenCV_DIR}/bin/Release/opencv_imgproc${Used_OpenCV_Version}.dll"
                  "${OpenCV_DIR}/bin/Release/opencv_core${Used_OpenCV_Version}.dll"
                  DESTINATION "plugins/DeviceA"
                  COMPONENT ${LIBRARY_NAME} 
                  CONFIGURATIONS Release
                 )
          

          Unfortunately, i can't dump my dependencies. I have plugins which have dependencies to OpenCV, OpenCL, proprietary SDKs, boost and so on..

          kshegunovK 1 Reply Last reply
          0
          • MarKSM MarKS

            @kshegunov I use CMake to configure my project. A sample plugin cmakelists.txt looks like this:

            # library name
            set(LIBRARY_NAME deviceA_plugin)
            
            add_library(${LIBRARY_NAME} 
                        SHARED 
                        ${Headers}
                        ${Sources}
                       )
                       
            # Link to libs
            target_link_libraries(${LIBRARY_NAME} 
                                  PRIVATE
                                  Boost::filesystem
                                  Boost::date_time
                                  Boost::regex
                                  opencv_core
                                  opencv_video
                                  opencv_videoio
                                  opencv_imgcodecs
                                  opencv_imgproc
                                  Qt5::Core                      
                                  )
            
            target_include_directories(${LIBRARY_NAME}  
                                       PRIVATE 
                                       ${CMAKE_CURRENT_SOURCE_DIR}
                                       ${CMAKE_CURRENT_SOURCE_DIR}/..
                                       ${CMAKE_CURRENT_SOURCE_DIR}/../..
                                      )
                                      
            set(Used_OpenCV_Version "${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}")
            
            install(TARGETS ${LIBRARY_NAME}
                    RUNTIME
                    DESTINATION "plugins/DeviceA"
                    COMPONENT ${LIBRARY_NAME} 
                    )
            
            install(FILES
                    "${OpenCV_DIR}/bin/Release/opencv_videoio${Used_OpenCV_Version}.dll"
                    "${OpenCV_DIR}/bin/Release/opencv_video${Used_OpenCV_Version}.dll"
                    "${OpenCV_DIR}/bin/Release/opencv_imgcodecs${Used_OpenCV_Version}.dll"
                    "${OpenCV_DIR}/bin/Release/opencv_imgproc${Used_OpenCV_Version}.dll"
                    "${OpenCV_DIR}/bin/Release/opencv_core${Used_OpenCV_Version}.dll"
                    DESTINATION "plugins/DeviceA"
                    COMPONENT ${LIBRARY_NAME} 
                    CONFIGURATIONS Release
                   )
            

            Unfortunately, i can't dump my dependencies. I have plugins which have dependencies to OpenCV, OpenCL, proprietary SDKs, boost and so on..

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by kshegunov
            #10

            Right, well you could try this instead (not tested), if that doesn't work ... well I'm starting to doubt it's possible to do ...:

            // Instead of QDir::setCurrent(pluginPathInfo.dir().path())
            auto handle = AddDllDirectory((PCWSTR) str.utf16());
            Q_ASSERT(handle);
            
            // QPluginLoader ... load code
            
            RemoveDllDirectory(handle);
            

            I'm not sure on windows there's something equivalent to the RPATH, but you could try setting it in the cmake file and see if it works.

            Read and abide by the Qt Code of Conduct

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

              Sadly it looks like Windows does not have that feature. At least based on the Microsoft documentation.

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

              kshegunovK 1 Reply Last reply
              0
              • SGaistS SGaist

                Sadly it looks like Windows does not have that feature. At least based on the Microsoft documentation.

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by
                #12

                @SGaist said in QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe:

                Sadly it looks like Windows does not have that feature.

                Which feature do you mean?

                Read and abide by the Qt Code of Conduct

                SGaistS 1 Reply Last reply
                0
                • kshegunovK kshegunov

                  Right, well you could try this instead (not tested), if that doesn't work ... well I'm starting to doubt it's possible to do ...:

                  // Instead of QDir::setCurrent(pluginPathInfo.dir().path())
                  auto handle = AddDllDirectory((PCWSTR) str.utf16());
                  Q_ASSERT(handle);
                  
                  // QPluginLoader ... load code
                  
                  RemoveDllDirectory(handle);
                  

                  I'm not sure on windows there's something equivalent to the RPATH, but you could try setting it in the cmake file and see if it works.

                  MarKSM Offline
                  MarKSM Offline
                  MarKS
                  wrote on last edited by MarKS
                  #13

                  @kshegunov It didn't work. We are running out of options aren't we? I still believe there must be a way to deal with this. I don't think big applications put all their dependencies in one place (application directory) so that windows can find them at run-time.

                  I preferred to build plugins the Qt-way because it is a bit easier to integrate into my Qt application. Now, i realize even, if i use
                  boost.dll to load plugins i will again run into this issue of windows not able to find the dependencies since it is an OS issue now. Or am i wrong?

                  kshegunovK 1 Reply Last reply
                  0
                  • MarKSM MarKS

                    @kshegunov It didn't work. We are running out of options aren't we? I still believe there must be a way to deal with this. I don't think big applications put all their dependencies in one place (application directory) so that windows can find them at run-time.

                    I preferred to build plugins the Qt-way because it is a bit easier to integrate into my Qt application. Now, i realize even, if i use
                    boost.dll to load plugins i will again run into this issue of windows not able to find the dependencies since it is an OS issue now. Or am i wrong?

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #14

                    @MarKS said in QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe:

                    I preferred to build plugins the Qt-way because it is a bit easier to integrate into my Qt application. Now, i realize even, if i use
                    boost.dll to build plugins i will again run into this issue of windows not able to find the dependencies since it is an OS issue now. Or am i wrong?

                    Well I'm pretty much out of ideas. A few years back (or at least to my knowledge) MS introduced SxS which is/was supposed to combat this particular problem, however I personally have no experience in deploying with it.

                    Additional link: https://docs.microsoft.com/en-us/windows/win32/sbscs/isolated-applications-and-side-by-side-assemblies-portal

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    0
                    • kshegunovK kshegunov

                      @SGaist said in QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe:

                      Sadly it looks like Windows does not have that feature.

                      Which feature do you mean?

                      SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #15

                      @kshegunov said in QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe:

                      @SGaist said in QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe:

                      Sadly it looks like Windows does not have that feature.

                      Which feature do you mean?

                      RPATH equivalent

                      @MarKS one other possibility could be to use a script to start your application that would first set the PATH environment variable to include the folders of your plugins.

                      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
                      2
                      • MarKSM Offline
                        MarKSM Offline
                        MarKS
                        wrote on last edited by
                        #16

                        this seems to be a promising idea. However, i would also need to unset the PATH variables when the application is terminated. I do not want to spam the users PATH variable if i keep on adding new plugins. I will try it out and will update here.

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

                          The goal of the script is to change the PATH locally for the script and start your application as well. Just like it's done by Firefox on Linux to ensure the bundled libraries are found.

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

                          kshegunovK 1 Reply Last reply
                          0
                          • SGaistS SGaist

                            The goal of the script is to change the PATH locally for the script and start your application as well. Just like it's done by Firefox on Linux to ensure the bundled libraries are found.

                            kshegunovK Offline
                            kshegunovK Offline
                            kshegunov
                            Moderators
                            wrote on last edited by
                            #18

                            @SGaist said in QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe:

                            The goal of the script is to change the PATH locally for the script and start your application as well. Just like it's done by Firefox on Linux to ensure the bundled libraries are found.

                            I don't believe that's going to work (properly), because to have this work the expected way the PATH should be modified between loading of the plugins, not at the time the executable is loaded ...

                            @MarKS, two more (rather more obvious suggestions):

                            1. Rename the dlls and libs each plugin uses, so the loader knows what to map where and link the plugin to each of the ones it needs. You can apply this with the usual deployment - put everything in the app dir. Granted it's not very clean, but it's (almost) guaranteed to work.

                            or

                            1. (And I hate myself for suggesting this, but we live in interesting times ...)
                              Link statically the libraries in the plugin. If you decide to go this way, do not forget to compile the libraries yourself and enable /GL on compilation and /LTCG at link time to have the MSVC do the LTO so you don't get overly fat binaries.

                            Read and abide by the Qt Code of Conduct

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

                              For number 2: only the non Qt stuff. Otherwise you'll have interesting issues with the QObject based classes meta object having multiple copies.

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

                              kshegunovK 1 Reply Last reply
                              0
                              • MarKSM Offline
                                MarKSM Offline
                                MarKS
                                wrote on last edited by
                                #20

                                While reading through Dynamic-Link Library Search Order i found out it is possible to modify the search order using SetDllDirectoryA() as described here. It finally worked.

                                Although, this would still be half the answer as it will fail in Linux or Mac. I believe there should be a way to achieve this in Linux but right now i am happy with windows. If you guys know how to achieve this in Linux or Mac please feel free to add your answer here.

                                Would help others.

                                1 Reply Last reply
                                1
                                • SGaistS SGaist

                                  For number 2: only the non Qt stuff. Otherwise you'll have interesting issues with the QObject based classes meta object having multiple copies.

                                  kshegunovK Offline
                                  kshegunovK Offline
                                  kshegunov
                                  Moderators
                                  wrote on last edited by
                                  #21

                                  @SGaist said in QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe:

                                  For number 2: only the non Qt stuff. Otherwise you'll have interesting issues with the QObject based classes meta object having multiple copies.

                                  Yes, yes, that's what I meant, I'm just not that good with putting words in place of thoughts ... ;)

                                  @MarKS said in QPluginloader error: "Cannot load library: The specified module could not be found" unless the plugin is in the same folder as in .exe:

                                  If you guys know how to achieve this in Linux or Mac please feel free to add your answer here.

                                  On Linux you can just modify the RPATH for the plugin binary. Should work out of the box.

                                  Read and abide by the Qt Code of Conduct

                                  1 Reply Last reply
                                  2

                                  • Login

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