PDA

View Full Version : QLibrary



Amita
22nd July 2011, 14:45
I want to load the library dynamically depending upon the users choice. How do I do it? QLibrary does not seem to just load the library when I do not put the library in LIBS += .... If I check lib.isLoaded(), it gives me true but I cannot use the library.
I have now idea how does this QLibrary works? Please help me out.
I am simply using QLibrary lib("libraryName"); lib.load().

Thank you very much in advance.

high_flyer
22nd July 2011, 14:47
I have now idea how does this QLibrary works?
How about reading the docs to start with?
QLibrary

Amita
22nd July 2011, 14:52
offcourse I started with reading the documentation first. But I could not understand most of the things like resolve() method. I did not fully understand the example given in the documentation :(.

high_flyer
22nd July 2011, 15:08
Well "not understand" is a very broad term, I can only repeat what is in the documentation, which is very good in my opinion, and if you can't understand the documentation, you probably wont understand anything I will write either (as the quality of the documentation is probably better than anything any of us here can write on a forum post).
Try to be more specific about what it is you don't understand, maybe we can help you then.

Amita
22nd July 2011, 15:27
Ok! First of all my problem:
I have two mount drivers - which is basically bundled up as dll files. Both of the libraries has same interface class. If I call the interface class, it will load the driver classes depending upon which library I load.
It works perfectly fine when I change .pro file LIBS += ... , before compiling the program.
Now I want to load the library dynamically, basically I want to give an option to the user which library (driver) he/she wants to use and load the driver accordingly.

For this, I thought QLibrary is the thing. I am even not sure if QLibrary is the right thing for my purpose. Anyways, I called QLibrary mylib("libraryName") and mylib.load(). Doing this the library is loaded (which is confirmed by mylib.isLoaded()). However, my program gives error.

In the documentation, resolve(QString symbol) method is mentioned. I did not understand what exactly is this "symbol". Is this the name of the class that I want to use from the library? If so how do I use it? I tried giving the name of the class as input variable to this method but it did not work. I am sorry, if I am being completely stupid here.

Thanks and looking forward to your suggestions.

high_flyer
22nd July 2011, 16:08
Well, a library exports functions, and each exported function is a symbol (plainly put).
So if you want to call function in the lib, you need the address of that function code, which you get by resolving the exported function symbol.
So if you look at the example (see comments):


QLibrary myLib("mylib");
typedef void (*MyPrototype)(); //<---- this is a function pointer type for the function you need
MyPrototype myFunction = (MyPrototype) myLib.resolve("mysymbol"); //Here the function pointer gets the address from the lib
if (myFunction)
myFunction(); //here, if the pointer is valid, you can call the function in points to.

Amita
25th July 2011, 11:30
Hi,
Thank you for the post. I seem to understand better now. But still I am not able to make it work. I think the real problem is exporting the symbol from the library. Actually this library is compiled in C++ so as per the documentation, I have to export it as extern "C". I am doing something wron I know.
let me explain my problem.
In my library I have a class called I_MountInterface. Now, I want to use this class in my main program using QLibrary. I am still not sure about how to call "symbol" in resolve method.
I did it in the following way:


I_MountInterface *mount;
typedef I_MountInterface* (*MyPrototypeOne)();
MyPrototypeOne myFunction = (MyPrototypeOne) lib.resolve(" new I_MountInterface");
if (myFunction){
mount = myFunction();
}
else std::cerr << "myFunction is not valid" << std::endl;

And I am not sure how to export I_MountInterface class as extern "C" in my library. For testing i did it like following in the constructor of I_MountInterface class in my library:


extern "C" MY_EXPORT I_MountInterface::I_MountInterface() {
std::cout << "I am number 2" << std::endl;
mountDriver = new I_MountDriver;
}

Thank you

high_flyer
25th July 2011, 14:18
This is not a Qt issue, but a general C++.
Google about exporting classes in DLLs.
In Qt, if you use Qt creator or the VisualStudio add in, you can select a project type which is a Qt library.
It will automatically add the correct export/import defines to your class declarations - but you should really first read about it and understand the general concept and how it works.

Amita
25th July 2011, 15:10
I am using Eclipse. Anyways, I will do some more research about it. Thanks

wysota
25th July 2011, 21:39
The general approach with resolving classes from C libraries is to have a base class definition that is linked to both the main application and the library and to have a subclass of that class defined in the library along with a factory method that instantiates object of the subclass and casts them to the base class. The approach is identical to using plugins. If all of the code is yours to design and implement, I suggest you indeed use the plugin approach (using QPluginLoader). Otherwise you'll have to resolve all the symbols you need from the library using QLibrary which can be pain in the... neck.

Amita
27th July 2011, 15:35
Thanks a lot for the idea of QPluginLoader. It took me some time to lean how to create plugin and use it. But at the end, it works like a charm.
Thanks again
Amita