深度解析 Qt 中動(dòng)態(tài)鏈接庫(kù)
本文介紹的是Qt 中動(dòng)態(tài)鏈接庫(kù),現(xiàn)在有些軟件有自動(dòng)升級(jí)功能,有些就是下載新的DLL文件,替換原來(lái)的動(dòng)態(tài)鏈接庫(kù),MFC好象也有類似機(jī)制,Qt還有一種方式,就是把一個(gè)QWidget子類,編譯成動(dòng)態(tài)鏈接庫(kù).然后根據(jù)動(dòng)態(tài)鏈接庫(kù)創(chuàng)建一個(gè)對(duì)象,返回QWidget子針,如果你的類不是QWidget的子類,就不能用這種方法了
QLibrary也是用來(lái)加載動(dòng)態(tài)鏈接庫(kù),但它創(chuàng)建出來(lái)返回的是某個(gè)"方法的指針"(不需要頭文件),而QPluginLoader創(chuàng)建返回的是"對(duì)象的指針"(對(duì)象中有哪些方法可調(diào)用,就要頭文件說(shuō)了,所以上面的例子中,需要提供一個(gè)接口頭文件)
昨天一個(gè)同事說(shuō)要把一個(gè)類做成DLL的形式,但這個(gè)類不是從QWidget繼承。 研究了一下,發(fā)現(xiàn)Qt提供了一個(gè)類QPluginLoader可以加載動(dòng)態(tài)鏈接庫(kù)。能把一個(gè)普通的類編譯生成DLL,通過(guò)QPluginLoader使用它。
寫(xiě)一個(gè)例子說(shuō)明吧:
工程A中,使用了這樣一個(gè)類,專門用來(lái)讓算所得稅;
- Tax.h
- class Tax
- {
- float incomeTax(int income);
- };
- Tax.cpp
- Tax::incomeTax(int income)
- {
- float res=(income-1600)*0.5;
- return res;
- }
- main.cpp
- Int main()
- {
- Tax taxobject;
- taxObject. incomeTax(2200);
- ............
- }
編譯后部署到機(jī)器上.
如果計(jì)稅方式變了,則incomeTax()必須改寫(xiě)了;
- Tax::incomeTax(int income)
- {
- float res=(income-2000)*0.3;
- return res;
- }
頭文件沒(méi)有變,只是修改了計(jì)稅方式,工程A必須重新編譯,然后重新部署; 如果工程A很大或部署的機(jī)器很多,代價(jià)就大了.
如果讓Tax類,單獨(dú)編譯成動(dòng)態(tài)鏈接庫(kù),再把Tax中的要被使用的接口寫(xiě)在另一個(gè)頭文件中,供工程A使用;每次計(jì)稅方式變了,只需修改Tax類,然后重新編譯生成動(dòng)態(tài)鏈接庫(kù),然后替換工程A中的相應(yīng)的動(dòng)態(tài)鏈接庫(kù).而工程A不用重新編譯即可使用新的計(jì)稅方式.
新建一工程B,專門用來(lái)把Tax類做成動(dòng)態(tài)鏈接庫(kù)的形式:
- //首先定義接口(只要一個(gè)頭文件即可)
- Tax.h
- class Tax
- {
- virtual float incomeTax(int income);
- };
- QT_BEGIN_NAMESPACE
- Q_DECLARE_INTERFACE(Tax,"TaxDLL/1.0"); //這個(gè)宏用聲明接口
- QT_END_NAMESPACE
然后從寫(xiě)一個(gè)具體業(yè)務(wù)類,繼承上面的接口和QObject,實(shí)現(xiàn)接口中定義的方法
- TaxPlugin.h
- class TaxPlugin:public QObject,Tax
- {
- Q_OBJECT
- Q_INTERFACES(Tax)
- public:
- float incomeTax(int income);
- };
- TaxPlugin.cpp
- TaxPlugin::incomeTax(int income)
- {
- float res=(income-1600)*0.5;
- return res;
- }
- Q_EXPORT_PLUGIN2(Tax, TaxPlugin); //這個(gè)宏用來(lái)導(dǎo)出動(dòng)態(tài)鏈接庫(kù)
編譯工程B,生成Tax.dll.
把工程Tax.dll和頭文件Tax.h,拷到工程A中,供工程A使用.
工程A中
- int main()
- {
- Tax *taxObject;
- QPluginLoader pluginLoader("Tax.dll");
- QObject *plugin = pluginLoader.instance();
- taxObject= qobject_cast<Tax *>(plugin);
- taxObject->incomeTax(2100);
- }
如果稅率變了,只要修改工程B中的類,然后重新編譯生成Tax.dll,替換工程A中原來(lái)的庫(kù).而工程A不必重新編譯即可使用新的計(jì)稅方式.
現(xiàn)在有些軟件有自動(dòng)升級(jí)功能,有些就是下載新的DLL文件,替換原來(lái)的動(dòng)態(tài)鏈接庫(kù)。
MFC好象也有類似機(jī)制
Qt還有一種方式,就是把一個(gè)QWidget子類,編譯成動(dòng)態(tài)鏈接庫(kù).然后根據(jù)動(dòng)態(tài)鏈接庫(kù)創(chuàng)建一個(gè)對(duì)象,返回QWidget子針,如果你的類不是QWidget的子類,就不能用這種方法了
QLibrary也是用來(lái)加載動(dòng)態(tài)鏈接庫(kù),但它創(chuàng)建出來(lái)返回的是某個(gè)"方法的指針"(不需要頭文件),而QPluginLoader創(chuàng)建返回的是"對(duì)象的指針"(對(duì)象中有哪些方法可調(diào)用,就要頭文件說(shuō)了,所以上面的例子中,需要提供一個(gè)接口頭文件)動(dòng)態(tài)
小結(jié):Qt 中動(dòng)態(tài)鏈接庫(kù) 的內(nèi)容介紹完了,希望本文對(duì)你有所幫助。