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就行了,因为这种情况下根本不存在跨模块对象传递的问题。



第十二篇:SOUI的utilities模块为什么要用DLL编译?的更多相关文章

  1. Python之路(第十二篇)程序解耦、模块介绍\导入\安装、包

    一.程序解耦 解耦总的一句话来说,减少依赖,抽象业务和逻辑,让各个功能实现独立. 直观理解“解耦”,就是我可以替换某个模块,对原来系统的功能不造成影响.是两个东西原来互相影响,现在让他们独立发展:核心 ...

  2. 第二十二篇 正在表达式 re模块

    re模块****** 就本质而言,正则表达式时一种小型的,高度专业化的编程语言,在python里,它内嵌在python中,并通过re模块实现.正则表达式模式被编译成一系列的字节码.然后用C编写的匹配引 ...

  3. Python开发【第二十二篇】:Web框架之Django【进阶】

    Python开发[第二十二篇]:Web框架之Django[进阶]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...

  4. 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探

    SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...

  5. Spring Cloud第十二篇 | 消息总线Bus

    ​ ​本文是Spring Cloud专栏的第十二篇文章,了解前十一篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring ...

  6. 解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)

    解剖SQLSERVER 第十二篇   OrcaMDF 行压缩支持(译) http://improve.dk/orcamdf-row-compression-support/ 在这两个月的断断续续的开发 ...

  7. 第十二篇 SQL Server代理多服务器管理

    本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...

  8. 第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  9. Python之路【第十二篇】:JavaScrpt -暂无内容-待更新

    Python之路[第十二篇]:JavaScrpt -暂无内容-待更新

随机推荐

  1. PHP入门笔记

    PHP是一种创建动态交互性站点的强有力的服务器端脚本语言.PHP其代码可以直接嵌入HYML代码.PHP语法非常类似于Perl和C,常常搭配Apache一起使用. 1.PHP是指超文本预处理器(Hype ...

  2. JavaBean转换为XML的源码

    package com.cmge.utils; import java.util.Iterator; import com.cmge.org.oa.bean.OADepartment; import ...

  3. lol 正在刷leetcode

    letcode easy 刷了90%了 我要写个随笔庆祝下 挑着做的太不要脸了,接下来要做剩下的了 :) 剩下的决定直接参考答案了 :) 有些答案看着也好迷糊.水平太差了.(英文水平差,看不懂题目.. ...

  4. 开始学习C++

    这里突然想起来当初学习java和C# 总是会有个demo :  hello  world. 这里我记得我曾经看过一个笑话.说有个程序员,想学习书法,买了笔墨,都准备好了,但是不知道写什么好.最后,他大 ...

  5. PHP javascript cookie

    2015-07-30 16:54:58 ................................cao!!!! 汉字, 邮箱的@符号 容易出错 PHP setcookie 的时候, 不要url ...

  6. BestCoder22 1002.NPY and arithmetic progression(hdu 5143) 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5143 题目意思:给出 1, 2, 3, 4 的数量,分别为a1, a2, a3, a4,问是否在每个数 ...

  7. 两种js数组去重的方法

    方法一: 新建一个数组,遍历原数组,在新数组内用IndexOf查找原数组内的每一项,如果没有找到,则添加到其中 代码如下: function arrayNew(arrs ){ var newArray ...

  8. php面向对象中的静态与抽象,接口

    静态又包括: 普通成员: 普通成员是属于对象的 静态成员: 静态成员是属于类的 关键字:static self关键字:在类里面代表该类,前面不用加$ 在静态方法里面不能调用普通成员 在普通方法里面能够 ...

  9. iOS 多线程及其他补充

      NSOperation NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类 NSInvocationOperation 如果直接执行NSInvocationOperatio ...

  10. Android笔记:获取屏幕信息

    像素密度(dpi) float xdpi = getResources().getDisplayMetrics().xdpi;float ydpi = getResources().getDispla ...