-
Notifications
You must be signed in to change notification settings - Fork 281
第十二篇:SOUI的utilities模块为什么要用DLL编译?
原文链接:《第十二篇:SOUI的utilities模块为什么要用DLL编译?》
SOUI相对于DuiEngine一个重要的变化就是很多模块变成了一个单独的DLL。
然后很多情况下用户可能希望整个产品就是一个EXE,原来DuiEngine提供了LIB编译模式,此时链接LIB模式的DuiEngine就行了。
但是SOUI默认至少Utilities那个模块是不提供LIB编译模式的。
utilities之所以默认只提供DLL编译是因为SString类是由utilities实现的。
字符串是编译中碰到的最最见的基本对象之一。在运行库(CRT)动态编译(MD,MDd)时这不是问题,因为所有模块的内存分配都是在一个相同的运行库(CRT)上,这时在不同模块之间传递对象相对简单。如果项目采用运行库静态编译(MT or MTd),在不同模块之间传递字符串对象是非常困难的,因为一不小心就会发生在A模块中分配的字符串对象被B模块释放。
utilities采用DLL编译就是为了解决这个字符串对象的跨模块传递。
采用运行库动态编译的情况就不说了,这里主要介绍采用静态库编译的CRT的情况。
SOUI中使用的字符串对象采用了一点技巧:每一个String对象中只有一个指针成员变量:
template <class tchar, class tchar_traits>
class TStringT
{
public:
typedef tchar _tchar;
typedef const _tchar * pctstr;
protected:
tchar* m_pszData; // pointer to ref counted string data
};
虽然TStringT是一个模板类,在SOUI中采用类导出的方式将该模板的两个特化类导出:
#ifdef UTILITIES_EXPORTS
# define EXPIMP_TEMPLATE
#else
# define EXPIMP_TEMPLATE extern
#endif
#pragma warning (disable : 4231)
EXPIMP_TEMPLATE template class UTILITIES_API TStringT<char, char_traits>;
EXPIMP_TEMPLATE template class UTILITIES_API TStringT<wchar_t, wchar_traits>;
通过将string类导出,保证string的所有运行代码都是在utilities这个模块内部,这也就保证了string对象的唯一成员变量:
tchar* m_pszData;
的内存分配及释放固定在utilities这个模块里。
通过这样处理,无论用户定义string是在哪一个模块,真正的内存管理还是在utilities里,从而使得string对象可以方便的在不同模块之间传递。
比较一下std::string就可以发现,如果使用std::string
在不同模块之间传递对象将是非常危险的,因为std::string
是模板类,它的代码将会被编译到不同的模块中,也就是说在不同的模块中调用std::string的成员函数执行的代码是不一样的,这样在A模块中声明的string传递到B模块再被B模块释放程序就崩溃了。
这就是为什么utilities模块默认只提供DLL编译的原因。
知道了原因就好办了。
对于那些希望整个项目就是一个EXE的情况,直接修改utilities模块的编译类型为LIB就行了,因为这种情况下根本不存在跨模块对象传递的问题。
UI? just so so!
- 第一篇:SOUI是什么?
- 第二篇:SOUI源码的获取及编译
- 第三篇:用SOUI能做什么?
- 第四篇:SOUI资源文件组织
- 第五篇:在SOUI中使用XML布局属性指引
- 第六篇:在SOUI中用九宫格拉伸方式显示一个图片资源
- 第七篇:创建一个SOUI的Hello World
- 第八篇:SOUI中控件事件的响应
- 第九篇:在SOUI中使用多语言翻译
- 第十篇:扩展SOUI的控件及绘图对象
- 第十一篇:SOUI系统资源管理
- 第十二篇:SOUI的utilities模块为什么要用DLL编译?
- 第十三篇:在SOUI中使用有窗口句柄的子窗口
- 第十四篇:在SOUI中使用定时器
- 第十五篇:在SOUI中消息通讯
- 第十六篇:SWindow的布局属性pos2type及offset
- 第十七篇:使用窗口的cache属性加速SOUI的渲染
- 第十八篇:在SOUI中实现PreTranslateMessage
- 第十九篇:提高SOUI应用程序渲染性能的三种武器
- 第二十篇:在SOUI中使用分层窗口
- 第二十一篇:SOUI中的控件注册机制
- 第二十二篇:在SOUI中使用代码向窗口中插入子窗口
- 第二十三篇:在SOUI中使用LUA脚本开发界面
- 第二十四篇:导出SOUI对象到LUA脚本
- 第二十五篇:在SOUI中做事件分发处理
- 第二十六篇:两个SOUI新控件 ---- SListView和SComboView
- 第二十七篇:SOUI中控件属性查询方法
- 第二十八篇:SOUI中自定义控件开发过程
- 第二十九篇:使用SOUI的SMCListView控件
- 第三十篇:SOUI模块结构图及SOUI框架图
- 第三十一篇:SOUI布局之相对于特定兄弟窗口
- 第三十二篇:在SOUI2.0中像android一样使用资源
- 第三十三篇:使用uiresImporter生成uires.idx及skin.xml
- 第三十四篇:在SOUI中使用异步通知
﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊
This wiki is created by [SOUI Team]