最近在修改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还有不少不错的设计,能够去阅读一下它的代码。接口