duilib库自己现在用的蛮舒服的,全部的代码自己也看几遍,对自己开发UI帮助蛮多。duilib一个小巧的directui库,基本满足能大部分开发。虽然有一些BUG,但不影响开发,只要自己明白的他的库原理其他就容易了。
自己开发当中时候为了使模块更加模块话,我直接把界面和业务封装在一个DLL里面,资源都放在压缩包里面并做为DLL的资源。对外只提供接口,就算需求变化了,要修改界面,但对外面来说,接口不变,他们什么都知道,这样降低耦合性。但项目开发当中发现我启动一个用DUILIB模块界面后,前面界面关闭不关闭后面你要启动另一个DUILIB写的DLL里面的界面,你会发现根本启动不了,过了一会就调试一个ASSERT(pRoot) 的诊断报错。我觉得很奇怪,我以前用MFC这样开发时候没有发现这样的问题。觉得一点的不科学。后面想到一个进程公用一个DLL,一个进程中内存是一样的。所以猜测用了全部变量。
自己后来分析Core里面 CPaintManagerUI ,里面有大量的类的静态变量,显然对应CPaintManagerUI 所有的实例是公用的。
static HINSTANCE m_hInstance;
static HINSTANCE m_hResourceInstance;
static CDuiString m_pStrResourcePath;
static CDuiString m_pStrResourceZip;
static bool m_bCachedResourceZip;
static HANDLE m_hResourceZip;
static short m_H;
static short m_S;
static short m_L;
static CStdPtrArray m_aPreMessages;
static CStdPtrArray m_aPlugins;
后面分析 m_hInstance 是有问题,每个DLL都有自己不同的m_hInstance ,除非我自己放EXE里面公用EXE的资源。显然DUILIB 作者根本没有考虑多DLL访问问题,估计没有考虑DUILIB在DLL的使用,只考虑在exe使用了。
我的解决办法:我不修改作者原来的代码,懒的麻烦。每个模块的DLL 对应的一个duilib的DLL ,但名字不是一样,因为同一个进程只能加载一份DLL。
这样就每个进程加载同一个DLL环境一样了。比喻直播模块:生成Duilib_Live。录播模块就要Duilib_Play,反正DUILIB 也不大,对程序大小没有太大影响。
duilib在自定义控件时候visit 默认是false,很多时候不注意就会发现怎么窗口不显示呢。。。
MFC 能够很好的与DUILIB结合,具体可以看网上哥们写的迅雷播放器的教程。
MFC 在DLL注意点有好多,一个就是句柄问题,每次创建时候要AFX_MANAGE_STATE(AfxGetStaticModuleState());
而且窗口对象不是栈上,一定要堆上,不然就会报错,自己没有具体找到他的原因,能用就行了。MFC 兼容太多东西,所以也不要说MFC不好。