MFC的一些实用的基础知识

MFC基本知识沉淀
服务器君一共花费了235.136 ms进行了5次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

一、_T()函数

_T("")是一个宏,他的作用是让你的程序支持Unicode编码。因为Windows使用两种字符集ANSI和UNICODE,前者就是通常使用的单字节方式,但这种方式处理象中文这样的双字节字符不方便,容易出现半个汉字的情况。而后者是双字节方式,方便处理双字节字符。

Windows NT的所有与字符有关的函数都提供两种方式的版本,而Windows 9x只支持ANSI方式。如果你编译一个程序为ANSI方式,_T实际不起任何作用。而如果编译一个程序为UNICODE方式,则编译器会把"Hello"字符串以UNICODE方式保存。_T和_L的区别在于,_L不管你是以什么方式编译,一律以UNICODE方式保存。

  • LPSTR:32bit指针指向一个字符串,每个字符占1字节。
  • LPCSTR:32-bit指针指向一个常字符串,每个字符占1字节。
  • LPCTSTR:32-bit指针指向一个常字符串,每字符可能占1字节或2字节,取决于Unicode是否定义。
  • LPTSTR:32-bit指针每字符可能占1字节或2字节,取决于Unicode是否定义。

L是表示字符串资源为Unicode的。比如 wchar_t Str[] = L"Hello World!"; 这个就是双子节存储字符了。

_T是一个适配的宏。当 #ifdef _UNICODE 的时候 ,_T就是L。没有#ifdef _UNICODE的时候,_T就是ANSI的。

比如:

LPTSTR lpStr = new TCHAR[32];
TCHAR* szBuf = _T("Hello");

以上两句使得无论是在UNICODE编译条件下都是正确编译的。而且MS推荐你使用相匹配的字符串函数。比如处理LPTSTR或者LPCTSTR 的时候,不要用strlen,而是要用_tcslen。否则在UNICODE的编译条件下,strlen不能处理 wchar_t*的字符串。

T是非常有意思的一个符号(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()...),它表示使用一种中间类型,既不明确表示使用 MBCS,也不明确表示使用 UNICODE。那到底使用哪种字符集?编译的时候才决定。

将char字符串转换成Unicode字符串。 T是个宏,不是函数。在需要双字节的函数,或COM里需要双字节的串。为了国际兼容。其实很简单。Visual C++里边定义字符串的时候,用_T来保证兼容性,VC支持ascii和unicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改。

如果将来你不打算升级到unicode,那么也不需要_T,_t("hello world") 在ansi的环境下,它是ansi的,如果在unicode下,那么它将自动解释为双字节字符串,既unicode编码。这样做的好处,不管是ansi环境,还是unicode环境,都适用。

在vc++中的字符串_T("ABC")和一个普通的字符串“ABC”有什么区别?_T("ABC")表示如果定义了unicode,它表示 L"ABC",每个字符为16位,宽字符字符串。if not UNICODE,它就是ascii的"ABC",每个字符为8位。"ABC"就是指ascii字符串"ABC"。相当于:

#ifdef _UNICODE
#define _T("ABC") L"ABC"
#else
#define _T("ABC") "ABC"
#endif

_T("ABC")中的一个字符和汉字一样,占两个字节,而在"ABC"中,英文字符占一个字节,汉字占两个字节。

二、堆和栈

1、“堆”和“栈”在C++中主要是指存放数据或者说是变量、对象的在内存中的区域,如同现实中美国和中国的区别,表面上是在内存中的位置不同,但是分配内存的方式却大不相同,如同美国和中国虽然表面上都是国家,但是社会制度、各种福利各种机构都不同,一句话就是内存中的不同区域。

2、C++中“堆”:在一个程序中堆是一片内存,不是有堆内存之说,一般都是程序员手动分配,在C++中则是一般用new操作符(如果不使用C的malloc系列,好像只能用new)分配的内存,同样也只能程序员手动释放,不然会有内存泄露。当然了给什么分配内存,那只能给变量、类对象分配,所以存放的也是类对象和变量。

3、C++中“栈”:是程序自动分配的内存,比如调用某个函数,传递参数时(值传递),那么这个参数的值是在“栈”内存上分配的,当这个函数退出后占用的“栈”内存也就自己释放了。

三、Windows Socket

Socket的实现方法:

Socket是连接应用程序与网络驱动程序的桥梁。它在应用程序中创建,通过绑定操作与驱动程序建立关系。此后,应用程序送给Socket数据,由Socket交给驱动程序,驱动程序再把数据向网络上发送出去。计算机从网络上收到与该Socket绑定的IP地址和端口号相关的数据后,由驱动程序交给Socket,应用程序便可从该Socket中提取接收到的数据。网络应用程序就是这样运用Socket进行数据的发送与接收的。

ISO/OSI七层参考模型(ISO:国际标准化组织 OSI:Open System Interconnection):

  • 物理层:提供二进制传输,确定在通信信道上如何传输比特流。
  • 数据链路层:提供介质访问,加强物理层的传输功能,建立一条无差错的传输线路。
  • 网络层:提供IP寻址和路由。因为在网络上数据可以经由多条线路到达目的地,网络层负责找出最佳的传输路线。
  • 传输层:为源端主机到目的端主机提供可靠的数据传输服务,隔离网络的上下层协议,使得网络应用与下层协议无关。
  • 会话层:在两个相互通信的应用进程之间建立、组织和协调其相互之间的通信。
  • 表示层:处理被传送数据的表示问题,即信息的语法和语义。

对等层通信的实质:对等层实体之间虚拟通信。下层向上层提供服务,实际通信在最底层完成。

各层所使用的协议:

  • 应用层:远程登录协议Telnet、文件传输协议FTP、超文本传输协议HTTP、域名服务DNS、简单邮件传输协议SMTP、邮局协议POP3。
  • 传输层:传输控制协议TCP、用户数据报协议UDP。
  • 网络层:网际协议IP、Internet互联网控制报文协议ICMP、Internet组管理协议IGMP。

TCP/IP模型:应用层、传输层、网络层、网络接口层。

TCP/IP模型与OSI模型对照如下:

  • 应用层:应用层、表示层、会话层。
  • 传输层:传输层。
  • 网络层:网络层。
  • 网络接口层:数据链路层、物理层。

端口:一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。

套接字的类型:

  • 流式套接字(SOCK_STREAM),基于TCP协议实现。
  • 数据报套接字(SOCK_DGRAM),UDP协议实现。
  • 原始套接字(SOCK_RAW)

Windows Socket “TCP”网络编程实例,一些开发步骤如下。
“TCP”服务器端:

  1. 加载套接字库。
  2. 创建套接字。
  3. 绑定地址信息。
  4. 绑定套接字。
  5. 监听套接字。
  6. “Accept”等待用户请求。
  7. “send”发送数据。
  8. "recv"接收数据。
  9. 关闭“使用中的套接字”,继续循环等待。

“TCP”客户端:

  1. 加载套接字库。
  2. 创建套接字。
  3. 绑定地址信息。
  4. 绑定套接字。
  5. 发出请求。
  6. 接收数据。
  7. 发送数据。
  8. 关闭套接字。
  9. “WSACleanup”终止“套接字库”的使用。(服务器端一直循环运行,所有没有)。

对于UDP通信,不需要建立连接,直接进行收/发就可以了。

四、多线程

1、程序和进程

程序是计算机指令的集合,它以文件的形式存储在磁盘上。而进程是正在运行的程序的实例。比如,我们编译生成的“exe”文件是一个可执行程序,存储在磁盘上就是程序。点击运行后,就启动了该程序的一个实例,我们称之为进程。一个程序可以有多个进程,也就是一个程序可以产生多个实例。

2、进程和线程

进程从来不执行任何东西,它是线程的容器,真正完成代码执行的是线程。单个进程可能包含若干个线程,但至少包含一个主线程。

3、进程的地址空间

系统赋予每个进程独立的虚拟地址空间。对于32位操作系统,运行32位的进程,这个地址空间是4G。因为对于32位指针来说,它的寻址的范围是2的32次方,即4G。这就是为什么32位操作系统,内存条一般不超过4G的原因。

4、虚拟内存。

在磁盘上有一个“pagefile.sys”文件,它是页文件,页文件透明的为应用程序增加了内存,这一部分就是虚拟内存。

5、线程。

  • 线程的内核对象:操作系统用来存放线程统计信息的小型的数据结构。
  • 线程栈:它用于维护线程在执行代码是所需要的所有函数参数和局部变量。

同一个进程的不同线程运行在同一个进程环境下,它们共享资源,所以可以非常容易的实现相互之间的通信。线程运行在操作系统为其分配的CPU时间片上,对于单核CPU,就要多个线程来回切换。多核CPU就可以实现多个线程的并发执行。采用多线程而不是多进程,是因为线程只有一个内核对象和一个栈,占用内存少。而对于进程每一个都要分配4GB的虚拟地址空间,占用资源多。而且进程切换需要交换整个地址空间。线程之间的切换只是执行环境的改变。

本文地址:http://www.nowamagic.net/librarys/veda/detail/950,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/950

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《人月神话》 弗雷德里克·布鲁克斯 (作者), 汪颖 (译者)

《人月神话》原文:The Mythical Man-Month: The Essays on Software Engineering, 2nd ed.在软件领域,很少能有像《人月神话》一样具有深远影响力并且畅销不衰的著作。Brooks博士为人们管理复杂项目提供了最具洞察力的见解。既有很多发人深省的观点,又有大量软件工程的实践。本书内容来自Brooks博士在IBM公司System/360家族和OS/360中的项目管理经验。该书英文原版一经面世,即引起业内人士的强烈反响,后又译为德、法、日、俄中等多种语言,全球销量数百万册。确立了其在行业内的经典地位。

更多计算机宝库...