4

I have 2 Qt plugins, main and helper, with main.dll loading helper.dll. I am able to successfully load main.dll with QPluginLoader when both main.dll and helper.dll are in the same folder. When helper.dll is absent and I try to load main.dll an exception gets thrown. That's understandable cause helper.dll cannot be found. My task is to successfully catch the thrown exception, rather than crashing the app. While debugging here is what Qt Creator displays:

enter image description here

The following code is not solving the problem, so I need to do something else...

std::exception_ptr eptr;
QPluginLoader pluginLoader(packagePath);
try
{
    pluginLoader.load();
}
catch(...)
{
    eptr = std::current_exception();
}
jpnurmi
  • 5,716
  • 2
  • 21
  • 37
santahopar
  • 2,933
  • 2
  • 29
  • 50
  • I suppose you throw the exception in the main.dll when helper.dll is not found or not? How do you load helper.dll? By using Qt framework somehow or ...? – Radek Mar 07 '16 at 21:25
  • @Radek, I am not throwing the exception. The moment I call instance() of QPluginLoader that's what throws the exception. I just can't catch it, hence my app crashes. I am loading main.dll, but main.dll internally uses helper.dll. – santahopar Mar 07 '16 at 21:28
  • It makes sense, because AFAIK Qt doesn't throw an exception. Than the bool value returned by `load()` would be interesting for both cases. I think the problem will be in part of main.dll where you load the helper.dll. For me it looks like an exception from the OS API and because you cannot catch it is weird. – Radek Mar 08 '16 at 08:01
  • @Radek, yes, it's the OS that returns that exception, and because it happens in a different process, I cannot catch it... – santahopar Mar 08 '16 at 17:11

2 Answers2

1

I believe in this case you should use the Windows __try / __except extensions:

__try 
{
   // guarded code
}
__except ( expression )
{
   // exception handler code
}

This kind of exceptions will let you catch SEH errors, you can find a detailed article on MSDN about it: https://msdn.microsoft.com/en-us/library/swezty51.aspx


Besides, but this is another topic, in order to terminate gracefully you could also use SetUnhandledExceptionFilter.

Matteo
  • 482
  • 3
  • 11
  • I did read about __try and __except. For some reason I could not have that code compiled in Qt creator, even though I had all the required header files from Microsoft and STL included. Can you please try it with Qt creator, have it compiled and post the code? Thanks!! – santahopar Mar 09 '16 at 17:40
0

I have been able to resolve this. The problem was that my Qt application was not deploying itself (something that a Qt application has to do when it needs to be run independent from Qt creator. I added script to the .pro file of Qt Creator project. Once I did that, I do not see a crash, but a friendly error message generated by calling QPluginLoader::errrorString(), if the call to QPluginLoader::load() returns false.

Here is what my code looks like:

QPluginLoader pluginLoader(m_packagePath);

bool bLoaded = pluginLoader.load();
if (bLoaded)
{
    QObject* plugin = pluginLoader.instance();
    m_metaObject = plugin->metaObject();
    if (m_metaObject == nullptr)
    {
        qCritical() << "Unable to obtain entry class of input plugin. Please check your plugin.";
        return false;
    }
}
else
{
    qCritical() << "Message from Qt plugin loader:";
    qCritical() << pluginLoader.errorString();
    qCritical() << "Please make sure your input Qt plugin along with its dependencies are deployed with winqtdeploy.exe and in the same folder as your plugin.";
    exit(-1);
}

I took the deployment script from another Stackoverflow post which can be found here:

Automatic Copy of Dependent Files in Qt Creator

Community
  • 1
  • 1
santahopar
  • 2,933
  • 2
  • 29
  • 50
  • It is interesting. It means you need to copy another dll's to the path. When i wrote some plugin a years ago, i do not remember i needed to do it. – Radek Mar 09 '16 at 19:09
  • @armanali Didn't you ask for a condition in which pluginLoader.load(); throws? Your own code cannot be the solution in such a case. – Matteo Mar 11 '16 at 14:02