先制作個簡單的動態鏈接庫,再在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();
【參考文獻】