Qt加载动态链接库

先制作个简单的动态链接库,再在Qt里面加载它。

【制作动态链接库】

先编写一个hello.c

1 #include <stdio.h>
2 int hello()
3 {
4     printf("hello world!\n");
5 }

在Linux下编译,生成hello.o:

gcc -c hello.c

编译成动态链接库libhello.so(注意:Linux下的动态链接库以lib开始命名):

gcc -shared -o libhello.so hello.o

 

【加载动态链接库】

在Qt中加载libhello.so,先创建一个空的Qt工程,添加新文件main.c,内容如下:

 1  #include <stdio.h>
 2  #include <QLibrary>
 3 
 4  int main(int argc, char *argv[])
 5  {
 6      QLibrary *hello_lib = NULL;
 7      //写清楚库的路径,如果放在当前工程的目录下,路径为./libhello.so
 8      hello_lib = new QLibrary("/home/libhello.so");
 9  
10      //加载动态库
11      hello_lib->load();
12      if (!hello_lib->isLoaded()) 
13      {
14          printf("load libhello.so failed!\n");
15          return 0; 
16      }
17  
18      //定义函数指针
19      typedef void (*Fun)();
20  
21      //resolve得到库中函数地址
22      Fun hello = (Fun)hello_lib->resolve("hello");
23      if (hello)
24      {
25           hello();
26      }
27  
28      //卸载库
29      hello_lib->unload();
30      return 0;
31  }

运行后输出:hello world!

 

还有一种方法:主程序在编译的时候加上-L. -llibxxx.so

 

【QLibrary的文档】

The QLibrary class loads shared libraries at runtime.

An instance of a QLibrary object operates on a single shared object file (which we call a "library", but is also known as a "DLL"). A QLibrary provides access to the functionality in the library in a platform independent way. You can either pass a file name in the constructor, or set it explicitly with setFileName(). When loading the library, QLibrary searches in all the system-specific library locations (e.g. LD_LIBRARY_PATH on Unix), unless the file name has an absolute path. If the file cannot be found, QLibrary tries the name with different platform-specific file suffixes, like ".so" on Unix, ".dylib" on the Mac, or ".dll" on Windows and Symbian. This makes it possible to specify shared libraries that are only identified by their basename (i.e. without their suffix), so the same code will work on different operating systems.

The most important functions are load() to dynamically load the library file, isLoaded() to check whether loading was successful, and resolve() to resolve a symbol in the library. The resolve() function implicitly tries to load the library if it has not been loaded yet. Multiple instances of QLibrary can be used to access the same physical library. Once loaded, libraries remain in memory until the application terminates. You can attempt to unload a library using unload(), but if other instances of QLibrary are using the same library, the call will fail, and unloading will only happen when every instance has called unload().

A typical use of QLibrary is to resolve an exported symbol in a library, and to call the C function that this symbol represents. This is called "explicit linking" in contrast to "implicit linking", which is done by the link step in the build process when linking an executable against a library.

Note: In Symbian resolving symbols using their names is supported only if the library is built as STDDLL. Otherwise ordinals must be used. Also, in Symbian the path of the library is ignored and system default library location is always used.

The following code snippet loads a library, resolves the symbol "mysymbol", and calls the function if everything succeeded. If something goes wrong, e.g. the library file does not exist or the symbol is not defined, the function pointer will be 0 and won't be called.

QLibrary myLib("mylib");
typedef void (*MyPrototype)();
MyPrototype myFunction = (MyPrototype) myLib.resolve("mysymbol");
if (myFunction)
    myFunction();

The symbol must be exported as a C function from the library for resolve() to work. This means that the function must be wrapped in an extern "C" block if the library is compiled with a C++ compiler. On Windows, this also requires the use of a dllexport macro; see resolve() for the details of how this is done. For convenience, there is a static resolve() function which you can use if you just want to call a function in a library without explicitly loading the library first:

typedef void (*MyPrototype)();
MyPrototype myFunction = (MyPrototype) QLibrary::resolve("mylib", "mysymbol");
if (myFunction)
    myFunction();

 

 

 

【参考文献】

http://blog.csdn.net/wanglin754/art9969icle/details/704

posted @ 2012-09-12 17:27  水芊芊  阅读(13363)  评论(0编辑  收藏  举报