Results 1 to 12 of 12

Thread: Plugin can load or not depending on whether my app is launched from Qt Creator or not

  1. #1
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Plugin can load or not depending on whether my app is launched from Qt Creator or not

    Hi, I am having an unexplained behaviour using Qt 4.7.3 and Qt Creator 2.2.1 on Windows 7 (everything works fine on Ubuntu 10.10 and Mac OS X 10.6 using the same versions of Qt and Qt Creator).

    Basically, my application relies on various plugins being loaded upon starting my application. Now, for some weird reason, there is one out of 10 plugins that doesn't load when running my application from outside Qt Creator while if I start my application from within Qt Creator, then the plugin loads fine! This is the case whether I build a debug or release version of my application.

    As I said, everything works fine on Linux and Mac OS X, so I am really puzzled as why that particular plugin doesn't load. Why that plugin?!

    I know it might be a very long shot, but is there something trivial that I might have overlooked?

    Here is some code that I use (before actually loading the plugin) to retrieve some information about the plugin itself:

    Qt Code:
    1. PluginInfo Plugin::info(const QString &pPluginFileName)
    2. {
    3. // Return the information associated to the plugin
    4.  
    5. PluginInfo pluginInfo;
    6.  
    7. typedef PluginInfo (*PluginInfoFunc)();
    8.  
    9. PluginInfoFunc pluginInfoFunc = (PluginInfoFunc) QLibrary::resolve(pPluginFileName,
    10. QString(name(pPluginFileName)+"PluginInfo").toLatin1().constData());
    11.  
    12. if (pluginInfoFunc)
    13. // The plugin information function was found, so we can extract the
    14. // information we are after
    15.  
    16. pluginInfo = pluginInfoFunc();
    17. else
    18. {
    19. // The plugin information funciton couldn't be found which means that
    20. // we are not dealing with an OpenCOR plugin
    21.  
    22. pluginInfo.type = PluginInfo::Undefined;
    23.  
    24. if (!name(pPluginFileName).compare("CellMLModelRepository")) {
    25. QLibrary lib(pPluginFileName);
    26.  
    27. if (lib.load())
    28. QMessageBox::information(0, QString("Info"), "Can load...");
    29. else
    30. QMessageBox::information(0, QString("Info"), QString("Can NOT load... [%1 | %2]").arg(pPluginFileName,
    31. QFileInfo(pPluginFileName).exists()?"YES":"NO"));
    32. }
    33. }
    To copy to clipboard, switch view to plain text mode 
    So, what happens is that I am trying to resolve a function which should be in my plugin. In all cases, it works but for that CellMLModelRepository plugin of mine. Having added some debug code, if the function cannot be found, I try to load the plugin using QLibrary which here fails for my CellMLModelRepository plugin even though QFile::exists() does report that the file exists...

  2. #2
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 162 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    Have you tried to output QLibary::errorString() ?
    This helps alot in tracking down such things :-)

    Maybe the plugin is not found at all, or some environment stuff (like QT_PLUGIN_PATH) is not set?

    HTH

  3. #3
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    Yes, indeed... However, QLibrary::errorString() only tells me that "the specified module could not be found". Yet, QFile::exists() tells me that my plugin does exist... and as mentioned in my original message, it works fine from within Qt Creator. As for QT_PLUGIN_PATH, I will have a look (didn't know about that one), but still I can't understand why my other plugins would load fine since they are in the exact same directory...

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,677
    Thanks
    13
    Thanked 1,596 Times in 1,524 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    Your library is failing to load because either:
    1. The library file itself does not exist.
    2. The library file depends on something that cannot be found when the environment is not being controlled by Qt Creator.
    3. The library file exists but is not a dynamically loadable library.

    If you are saying that 1 does not apply then my money is on option 2. Given that you are afflicted with Windows then the problem is that whatever you are depending on is not in the system PATH. If it runs in the IDE then this quite likely a Qt library, but it could anything else you have added to the IDE run-time PATH.

  5. #5
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    #1 definitely doesn't apply indeed. Same with #3. So, it leaves #2.

    Ok, something which for some reason I hadn't mentioned before is the fact that the plugin in question (CellMLModelRepository) requires another of my plugins (Core). Now, the way I am loading my plugins is by checking my plugin folder for files with, on Windows, an extension of .dll. This means that my application would normally try to load my CellMLModelRepository plugin before my Core plugin. However, each of my plugins contains a function which provides my application with some information about it (type of plugin and its dependencies, if any). Basically, I have (on Windows) something like:
    Qt Code:
    1. extern "C" __declspec(dllexport) PluginInfo CellMLModelRepositoryPluginInfo();
    To copy to clipboard, switch view to plain text mode 
    Now, what I thought I would do (and in fact do, except that it doesn't work in the case I have described in my original message) is to use QLibrary::resolve to load that function and retrieve the plugin's dependencies. This means that in the case of my CellMLModelRepository plugin, my application would find out that it requires my Core plugin and would therefore try to load my Core plugin before loading (using QPluginLoader) my CellMLModelRepository plugin.

    Well, now, I am starting to think that even though I only want to resolve a 'self-contained' function in my CellMLModelRepository plugin, I would still need to load my Core plugin first. So, to test that hypothesis, I reworked my Core plugin to become a Bore plugin , and... well... bingo, it works now!

    So, it seems like I might finally have the cause of my problem. Two things now. First, why is it that my problem doesn't occur when I run my application from within Qt Creator (I am happy to accept that things are different on Linux and/or Mac OS X, hence I am not asking about those environments)? Secondly, is there really no way for me to extract from my plugin what its dependencies are? I would expect it to be possible since, after all, Dependency Walker does it... Alternatively, I could do the same as Qt Creator, i.e. first read an XML file that contains some information about the plugin and then load the plugin itself (after having loaded its dependencies first). I don't like that solution though. I like the idea of my plugins consisting of only one file and not two of them...

    === AFTER SOME MORE TESTING... ===

    Hmm... I just tried something which is to make a copy of my Core plugin to the folder where my application executable is, and... everything works fine. So, if anything, it does confirm that the issue was my CellMLModelRepository plugin does require my Core plugin and that it couldn't find it, hence even a 'simple' QLibrary:resolve wouldn't work.

    Oh! Now, I understand why it works fine when running my application from within Qt Creator, but not from outside it! This is because when running my application from within Qt Creator, all my binary files (EXE + DLLs) are in the same folder... while this is not the case when I did my test by running my application from outside Qt Creator (the EXE would be in a specific folder while my DLLs (plugins) would be in another, and corresponds to the case where my files have been deployed). Doh!!

    Ok, one more thing I don't understand (but won't try to 'crack' as it's getting late here!) is why is it that adding my plugins' folder using QCoreApplication::addLibraryPath didn't solve my problem...?
    Last edited by agarny; 3rd July 2011 at 04:18.

  6. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,677
    Thanks
    13
    Thanked 1,596 Times in 1,524 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    Ok, one more thing I don't understand (but won't try to 'crack' as it's getting late here!) is why is it that adding my plugins' folder using QCoreApplication::addLibraryPath didn't solve my problem...?
    The path you are setting inside Qt is the path it will use to file "LibraryB.dll" when you ask for it, but it is the operating system that has to resolve run time dependencies when Qt tries to load LibraryB. When the operating system loads the dynamic library it has to be able to find the other libraries that it depends on. If they are are already loaded in the application address space then the should be no issue. If not the operating system uses the operating system's mechanisms to find a library to satisfy the requirement and fails if it cannot do so. This is outside of Qt.

    If you have LibraryB that needs LibraryA then either explicitly load LibraryA first, or tell the operating system how to find LibraryA.

  7. #7
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    Quote Originally Posted by ChrisW67 View Post
    The path you are setting inside Qt is the path it will use to file "LibraryB.dll" when you ask for it, but it is the operating system that has to resolve run time dependencies when Qt tries to load LibraryB. When the operating system loads the dynamic library it has to be able to find the other libraries that it depends on. If they are are already loaded in the application address space then the should be no issue. If not the operating system uses the operating system's mechanisms to find a library to satisfy the requirement and fails if it cannot do so. This is outside of Qt.

    If you have LibraryB that needs LibraryA then either explicitly load LibraryA first, or tell the operating system how to find LibraryA.
    Ok, so the question for me is: is there a way to tell Windows where to find my plugins?

    I am currently working on another way to get things to work, but that requires extracting the dependencies of my plugins from the .dll file, and though I have it all figured out in my head, it's a solution I would rather avoid, if at all possible (it looks a bit like a hack).

  8. #8
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    For information, I have found some code (at http://pastebin.com/XNMtZF8G) which can be used to extract a DLL's dependencies. I have reworked that code quite a bit so that it does only what I need. For those who are interested, they can find 'my' code at https://github.com/opencor/opencor/b...ins/plugin.cpp (look for the Plugin::dependencies method).

    With the above, I am now going to be able to retrieve some information about my plugins, but QLibrary::resolve a self-contained function in my plugin. The issue I had on Windows was that if that plugin depended on other plugins (not 'visible' to the system), then my application couldn't retrieve the information and then load the plugin. Now, with the above reworked code, I will be able to do it. It's rather crazy, I know, but the whole point of this is that I can have all of my plugins in their own folder (which is nice and clean, and as is the case for Qt Creator) without the need for an additional (XML, for example) file that contains some information about the plugin itself (i.e. as Qt Creator does, but which I find 'unclean').

  9. #9
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,677
    Thanks
    13
    Thanked 1,596 Times in 1,524 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    http://msdn.microsoft.com/en-us/libr...=vs.80%29.aspx
    With both implicit and explicit linking, Windows first searches for "known DLLs", such as Kernel32.dll and User32.dll. Windows then searches for the DLLs in the following sequence:
    • The directory where the executable module for the current process is located.
    • The current directory.
    • The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.
    • The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.
    • The directories listed in the PATH environment variable.

  10. #10
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    Argh! Why? Well, because I spent/wasted quite some time yesterday trying to come up with a working solution to my problem (which I did) while all I had to do was to use QDir::setCurrent() with the path to my plugins. I have just tried it and, as expected, it works fine. Doh! Well, still learning every day...

  11. #11
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,677
    Thanks
    13
    Thanked 1,596 Times in 1,524 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    That has side effects with respect to file open/save dialogs and the like if they are allowed to default to the current working directory.

  12. #12
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Plugin can load or not depending on whether my app is launched from Qt Creator or

    Yes and this is the reason I am changing the directory just before loading the plugin and changing it back immediately after.

Similar Threads

  1. QPluginLoader not load plugin
    By Thyago.celler in forum Qt Programming
    Replies: 9
    Last Post: 20th May 2011, 20:01
  2. QPluginloader load plugin from RAM
    By meCHAoT in forum Qt Programming
    Replies: 3
    Last Post: 3rd February 2011, 18:23
  3. Qt Creator doesn't load nested plugin
    By skepticalgeek in forum Qt Tools
    Replies: 0
    Last Post: 9th January 2010, 22:10
  4. Driver loaded only when launched from Creator
    By vieraci in forum Qt Tools
    Replies: 0
    Last Post: 16th September 2009, 03:56

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.