最近在修改Meshlab的源代碼,使其可以展現咱們本身的數據格式。看Meshlab源代碼的時候發現它的架構很是漂亮,所以決定好好研究一下,後面其餘代碼重構的時候能夠參考這個架構。git
Meshlab使用Qt實現,總體工程由主窗體和多個子功能模塊組成,使用Subdirs工程文件進行子項目的組織。各個子模塊與主窗體是鬆耦合的,編譯時不相互依賴,編譯完成以後主窗體加載模塊的動態連接庫,若是沒有相應的庫或者加載失敗則沒有相應功能,而不影響其餘功能。github
我編譯時使用以下的一個Subdirs工程文件架構
TEMPLATE= subdirs CONFIG+= ordered SUBDIRS= common \ meshlab \ meshlabplugins/io_rawdata
一共編譯三個子工程,common,meshlab
以及io_rawdata
,前兩個工程是Meshlab的基礎,是必需編譯的,最後一個是可選的功能模塊。下面分別介紹一下這三個子工程。函數
common
工程編譯出來是一個靜態庫,其餘全部的工程都須要連接這個靜態庫common.lib
,這個工程只是負責接口的聲明,功能由具體的模塊實現,由主窗體調用。好比我編寫以下的一個接口聲明一個純虛函數testFunc
,這個函數會由io_rawdata
實現,並在meshlab
中被調用。測試
class RawDataIOInterface { public: RawDataIOInterface(){} virtual int testFunc()=0; }; #define RawDataIOInterface_IID "com.dinglufe.RawDataIOInterface" Q_DECLARE_INTERFACE(RawDataIOInterface,RawDataIOInterface_IID)
meshlab
工程是主窗體部分,也是整個工程的核心,負責界面和交互,其餘的一些工程經過加載動態連接庫使用。好比能夠加載io_rawdata.dll
使用RawDataIOInterface
中聲明的testFunc
,測試代碼以下.net
#include <common/rawdataiointerface.h> #include <QPluginLoader> #include <QDebug> void testRawDataFunc() { QPluginLoader loader("plugins/io_rawdata.dll"); QObject *plugin = loader.instance(); RawDataIOInterface *iRawDataIO = qobject_cast<RawDataIOInterface *>(plugin); qDebug()<<iRawDataIO->testFunc(); }
最後是io_rawdata
工程,這是一個工程模塊,這個模塊負責io
相關的一些功能,好比讀取咱們本身的文件格式,一樣依賴於common
工程獲取相應的接口,而後實現其中聲明的功能,好比以下一段測試代碼設計
#include <common/rawdataiointerface.h> class RawDataIO : public RawDataIOInterface { Q_OBJECT Q_PLUGIN_METADATA(IID RawDataIOInterface_IID) Q_INTERFACES(RawDataIOInterface) public: RawDataIO():RawDataIOInterface(){} int testFunc(){return 1;} };
實現了RawDataIOInterface
所聲明的testFunc
函數。code
固然了,以上說的這些東西都只不過是QPlugin
的使用簡介而已。關於代碼的組織,meshlab還有不少不錯的設計,能夠去閱讀一下它的代碼。接口