QLibrary is not loading DLL - qt

I want to load DLL in a C++ program and create function pointers. To avoid any confusion, I am providing the absolute path of the DLL. But still, the DLL is not loaded.
My Code:
void CallFunctionPointers()
{
QString strMsg;
QString strLibPath("D:\\dll\\AtmoRemote.dll");
QLibrary* m_p_lib = new QLibrary();
m_p_lib->setFileName(strLibPath);
if (!m_p_lib->load())
{
strMsg = QString("Could not load %1").arg(strLibPath); //<<<<-----------PROGRAM ALWAYS ENTERS HERE
}
else
{
strMsg = QString("Successfully loaded: %1").arg(strLibPath);
}
}

There may be many reasons, impossible to diagnose with the details provided here.
For instance: the process using Qt is 64 bits and the DLL is 32 bits. Or vice-versa. Another one: the DLL depends on other DLLs not available by QLibrary. My suggestion for you: use dependency walker or a similar utility to diagnose these issues.

Check for the error.
QString QLibrary::errorString() const
Returns a text string with the description of the last error that occurred. Currently, errorString will only be set if load(), unload() or resolve() for some reason fails.

Related

Qt: How to lock/prevent a file from being read while it is written?

I am using Qt5 on Windows 7.
In my current project I open a binary file in order to populate it with data coming from a TCP socket.
Normally, after the file is populated, I close it and another application will read this binary file for further processing.
Well, the problem is: The writing operation takes about 4-5 seconds (or even more) so I need to find a way to prevent the other application from reading from the binary file until the file is completely populated...
Here below is the code (yet I suppose it won't help much):
int error = 0;
unsigned long dataLength;
char dataBuffer[1500];
QFile localFile("datafile.bin");
//
localFile.open(QIODevice::WriteOnly);
while(error == 0)
{
error = readSocket(dataBuffer, &dataLength);
if(error == 0)
{
localFile.write(dataBuffer, dataLength);
}
else
{
error = -1;
}
}
localFile.close();
I am thinking about using a temporary file and rename it after the write operation is complete.
But maybe there is another better/smarter idea? Some kind of "lock file for reading" maybe...?
If you have the source to both applications, then the one writing the file can signal the other application by one of many IPC mechanisms (e.g. local sockets) that it has finished writing.
Alternatively, write to a file with a different filename and then rename / copy the file to the location expected by the reading application, when the write has finished.
However, it is advisable to use QSaveFile, rather than QFile when writing out files. As the documentation states: -
While writing, the contents will be written to a temporary file, and if no error happened, commit() will move it to the final file
So this will likely solve the problem for you.
I know maybe it's a little bit too late, but I recently found an interesting solution, i.e. a component named "Locked File":
The QtLockedFile class extends QFile with advisory locking functions.
This class extends the QFile class with inter-process file locking
capabilities. If an application requires that several processes should
access the same file, QtLockedFile can be used to easily ensure that
only one process at a time is writing to the file, and that no process
is writing to it while others are reading it.
class QtLockedFile : public QFile
{
public:
enum LockMode { NoLock = 0, ReadLock, WriteLock };
QtLockedFile();
QtLockedFile(const QString &name);
~QtLockedFile();
bool open(OpenMode mode);
bool lock(LockMode mode, bool block = true);
bool unlock();
bool isLocked() const;
LockMode lockMode() const;
private:
LockMode m_lock_mode;
};
This link will lead you to the right place, where the QLockedFile class implementation is:
https://github.com/kbinani/qt-solutions/tree/master/qtlockedfile
** So, I decided to share this info, maybe other Qt-users are interested! **

QPluginLoader.instance() - how does it really work?

I am currently working on a Qt project where dynamic plugin loading is central. I am loading DLLs by using Qt's QPluginLoader. The different plugins are accessed through CameraPluginStructs, defined as follows:
struct CameraPluginStruct
{
QString name;
QString filePath;
CameraPluginInterface* plugin;
QPluginLoader* pluginLoader;
CameraPluginStruct(QString filePath=nullptr, QString name=nullptr):
filePath(filepath), name(name), plugin(nullptr), pluginLoader(nullptr){}
};
To load a plugin, the following function is called:
void loadPlugin(CameraPluginStruct& p)
{
p.pluginLoader = new QPluginLoader(p.filePath);
p.pluginLoader->load();
QObject* possiblePlugin = p.pluginLoader->instance(); //QPluginLoader.instance();
if(possiblePlugin)
{
// cast from QObject to correct type:
p.plugin = qobjectcast<CameraPluginInterface>(possiblePlugin);
}
}
And to unload a plugin, I use this function:
void unloadPlugin(CameraPluginStruct& p)
{
p.pluginLoader->unload(); // QPluginLoader.unload();
p.pluginLoader->~QPluginLoader();
p.pluginLoader = nullptr;
p.plugin = nullptr;
}
I have made a few, simple test plugins that write messages to the console when the constructor is called. For simplicity, let's say that I have two test plugins, DLL A and DLL B. When I load A by using the loadPlugin() function, the constructor in the plugin is called, and the corresponding message is written in the console. I can do the same thing with B, and everything seems to work – B's constructor message is written to the console, and the other functions seem to work as well.
Now, the problem occurs when I try to create another CameraPluginStruct connected to either A or B. No message is written to the console, which leads me to think that the constructor is not called. Even though, I am able to call the other test functions in the plugin with success (DoSomething(), see below). If I unload all CameraPlugins connected to A or B, and then load the DLL again, the constructor is called again on the first load.
The QPluginLoader.instance() call is described as follows in the documentation:
"Returns the root component object of the plugin. (...) The component object is a QObject. Use qobject_cast() to access interfaces you are
interested in." http://doc.qt.io/qt-5/qpluginloader.html#instance
Wouldn't it then be natural that the constructor in the DLL would be called each time, and not only the first time?
As I've understood, a DLL is only loaded once for any program. Therefore I have also tried to use only one QPluginLoader per DLL file, with the same result. Qt also says that:
"Multiple instances of QPluginLoader can be used to access the same physical plugin." http://doc.qt.io/qt-5/qpluginloader.html#details
Therefore I can't see how this can be a source to the problem anyway.
I would really appreciate if anyone could clarify how the QPluginLoader.instance() really works. Why is the constructor – at least how it seems – only called the first time I use the instance() call?
Thank you!
Here is the code found in the DLLs (the output texts differ in A and B):
TestDLL::TestDLL()
{
std::cout << "This is written from the constructor in A \n";
}
QString TestDLL::Name() const
{
return "Hello, writing from Name() \n";
}
void TestDLL::DoSomething() const
{
qDebug() << "Hello, this text comes from DoSomething()"\n;
}
When your plugin is loaded (i.e. the first time QPluginLoader::instance() is called), then a single instance of it is created - this is your root instance. The root instance is the only instance QPluginLoader will ever create for you.
If you want more, then you create a createInstance() or clone() method for your plugin class, so that new instances can be created from the root instance. Or more conventionally, make your plugin class a factory for the class type you wish to expose.

QVariantMap crash in destructor

I am building a JSON-object with Qt and convert it to a QString using QJson. This (normally) works fine and it does in this case but in the destructor of my Qt data structure, it crashes with an Access Violation. The Object is built fine, it is sent over my network connection and after the function ends, my application crashes.
My code looks like this:
void bar()
{
QVariantMap data;
data.insert("Id", 1);
QList<QVariant> list; //QVariantList
for (QMap<...>:ConstIterator ... ) //Loop through a Map
{
QMap<QString, QVariant> singleEntry; //QVariantMap
singleEntry.insert("LocalId", it.value());
QList<QVariant> entryList; //QVariantList
for (...) //Loop through another structure
{
entryList.append("foo");
}
singleEntry.insert("List", entryList);
list.append(singleEntry);
}
data.insert("Entries", list);
QJson::Serializer.serialize(data); // Works fine
} // Crash here
If I remove the inner loop, which builds up entryList, everything works fine. It seems that the destructor of data cannot delete the contents but I have no idea, why. The whole data structure seems to be fine while serializing it (and I hope that QJson does not change anything in the given data) but it cannot be cleaned up..
Best Regards,
Tobias
As Raiv said this can happen when mixing debug and release dlls, but in my oppinion this can also happen if the application and the Qt DLL's use different CRT libraries. Some people say that when they recompiled Qt on their machines the problem dissapears and I think this is because the CRT dlls after Qt rebuild are the same as the app's. Try to set the Runtime Library option in C/C++ Code Generation is set to Multi-threaded Debug DLL (/MDd) or Multi-threaded DLL (/MD) respectively for Debug and Release. Some Qt types as QVariantMap, QVariantList, QModelIndexList are probably allocated with /MD (in Qt's dll) and when they are deallocated with /MT (in the app) I think this causes the crash. This can also fix the crash on QString::toStdWString(). In order for this to link maybe the Ignore All Default Libraries should be set to No and Ignore Specific Library should not mention crt dlls used by Qt.
I got a little workaround, which fits my needs. I have still no idea, why this crash happens, but I know, which should be the problem.
I tried to build up a static structure like this:
QVariantMap
QVariantList
QVariantMap
QVariantList
and it crashes. If I remove the QVariantList at the bottom and add QVariantMap or anything else instead, it is working fine. I think this is a problem with the nesting level in this case.
I have now just joined my list as a comma-seperated QString and then it works fine.
If anyone of you has an idea, why the crash in destructing such a nested struct (another information: doesnt matter if a allocate the QVariants in heap and delete them myself or stack) and how to fix it, please let me know.

ld linker question: the --whole-archive option

The only real use of the --whole-archive linker option that I have seen is in creating shared libraries from static ones. Recently I came across Makefile(s) which always use this option when linking with in house static libraries. This of course causes the executables to unnecessarily pull in unreferenced object code. My reaction to this was that this is plain wrong, am I missing something here ?
The second question I have has to do with something I read regarding the whole-archive option but couldn't quite parse. Something to the effect that --whole-archive option should be used while linking with a static library if the executable also links with a shared library which in turn has (in part) the same object code as the static library. That is the shared library and the static library have overlap in terms of object code. Using this option would force all symbols(regardless of use) to be resolved in the executable. This is supposed to avoid object code duplication. This is confusing, if a symbol is refereed in the program it must be resolved uniquely at link time, what is this business about duplication ? (Forgive me if this paragraph is not quite the epitome of clarity)
Thanks
There are legitimate uses of --whole-archive when linking executable with static libraries. One example is building C++ code, where global instances "register" themselves in their constructors (warning: untested code):
handlers.h
typedef void (*handler)(const char *data);
void register_handler(const char *protocol, handler h);
handler get_handler(const char *protocol);
handlers.cc (part of libhandlers.a)
typedef map<const char*, handler> HandlerMap;
HandlerMap m;
void register_handler(const char *protocol, handler h) {
m[protocol] = h;
}
handler get_handler(const char *protocol) {
HandlerMap::iterator it = m.find(protocol);
if (it == m.end()) return nullptr;
return it->second;
}
http.cc (part of libhttp.a)
#include <handlers.h>
class HttpHandler {
HttpHandler() { register_handler("http", &handle_http); }
static void handle_http(const char *) { /* whatever */ }
};
HttpHandler h; // registers itself with main!
main.cc
#include <handlers.h>
int main(int argc, char *argv[])
{
for (int i = 1; i < argc-1; i+= 2) {
handler h = get_handler(argv[i]);
if (h != nullptr) h(argv[i+1]);
}
}
Note that there are no symbols in http.cc that main.cc needs. If you link this as
g++ main.cc -lhttp -lhandlers
you will not get an http handler linked into the main executable, and will not be able to call handle_http(). Contrast this with what happens when you link as:
g++ main.cc -Wl,--whole-archive -lhttp -Wl,--no-whole-archive -lhandlers
The same "self registration" style is also possible in plain-C, e.g. with the __attribute__((constructor)) GNU extension.
Another legitimate use for --whole-archive is for toolkit developers to distribute libraries containing multiple features in a single static library. In this case, the provider has no idea what parts of the library will be used by the consumer and therefore must include everything.
An additional good scenario in which --whole-archive is well-used is when dealing with static libraries and incremental linking.
Let us suppose that:
libA implements the a() and b() functions.
Some portion of the program has to be linked against libA only, e.g. due to some function wrapping using --wrap (a classical example is malloc)
libC implements the c() functions and uses a()
the final program uses a() and c()
Incremental linking steps could be:
ld -r -o step1.o module1.o --wrap malloc --whole-archive -lA
ld -r -o step2.o step1.o module2.o --whole-archive -lC
cc step3.o module3.o -o program
Failing to insert --whole-archive would strip function c() which is anyhow used by program, preventing the correct compilation process.
Of course, this is a particular corner case in which incremental linking must be done to avoid wrapping all calls to malloc in all modules, but is a case which is successfully supported by --whole-archive.
I agree that using —whole-archive to build executables is probably not what you want (due to linking in unneeded code and creating bloated software). If they had a good reason to do so they should have documented it in the build system, as now you are left to guessing.
As to your second part of the question. If an executable links both a static library and a dynamic library that has (in part) the same object code as the static library then the —whole-archive will ensure that at link time the code from the static library is preferred. This is usually what you want when you do static linking.
Old query, but on your first question ("Why"), I've seen --whole-archive used for in-house libraries as well, primarily to sidestep circular references between those libraries. It tends to hide poor architecture of the libraries, so I'd not recommend it. However it's a fast way of getting a quick trial working.
For your second query, if the same symbol was present in a shared object and a static library, the linker will satisfy the reference with whichever library it meets first.
If the shared library and static library have an exact sharing of code, this may all just work. But where the shared library and the static library have different implementations of the same symbols, your program will still compile but will behave differently based on the order of libraries.
Forcing all symbols to be loaded from the static library is one way of removing confusion as to what is loaded from where. But in general this sounds like solving the wrong problem; you mostly won't want the same symbols in different libraries.

How can you get NVelocity to initialize correctly?

I can't get NVelocity to initialize. I'm not trying to do anything complicated, so it's just fine if it initializes at the defaults, but it won't even do that.
This:
VelocityEngine velocity = new VelocityEngine();
ExtendedProperties props = new ExtendedProperties();
velocity.Init(props);
Results in: "It appears that no class was specified as the ResourceManager..."
So does this:
VelocityEngine velocity = new VelocityEngine();
velocity.Init();
I can find precious little documentation on what the properties should be, nor how to get it to initialize with the simple defaults. Can anyone point to a resource?
A lot of pages point back to this page:
http://www.castleproject.org/others/nvelocity/usingit.html
But this page skips over the (seemingly) most important point -- how to set the properties and what to set them to.
I just want to load a simple template from a file.
Here's what I found out --
I was using the original NVelocity library, which hasn't had an update since 2003. I think it's a dead project.
I switched to the Castle Project version, and it's much easier -- in fact, it runs much like the examples on the page I linked to. It seems to set intelligent defaults for properties. I can initialize it without any properties set, but the template directory defaults to ".", so I generally set that one (do it before running "init").
To get the correct DLL, you need to download the latest NVelocity release (as of this writing it's 1.1).
Castle Project Download Page
You need to include the following files in your assembly, and make sure that their type is set to "Resource"
src\Runtime\Defaults\directive.properties
src\Runtime\Defaults\nvelocity.properties
These will then be found by ResourceLocator
src\Runtime\Resource\Loader\ResourceLocator.cs
If you get an exception on GetManifestResourceNames() as I did when trying to run Dvsl, then try modifying the ResourceLocator constructor to catch and ignore the error since the required files are in your local assembly (if you included them above) and the exception is only thrown by external assemblies (no idea why).
foreach(Assembly a in assemblies) {
String prefix = a.FullName.Substring(0,a.FullName.IndexOf(",")).ToLower();
try
{
String[] names = a.GetManifestResourceNames();
foreach (String s in names)
{
if (s.ToLower().Equals(fn) || s.ToLower().Equals(prefix + "." + fn))
{
this.filename = s;
assembly = a;
isResource = true;
}
}
} catch {
}
}

Resources