﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-再别流年的技术实验室-随笔分类-Win32与VC</title><link>http://www.cppblog.com/lf426/category/6572.html</link><description>Game Design Using C++ and SDL</description><language>zh-cn</language><lastBuildDate>Sun, 06 Jun 2010 14:15:51 GMT</lastBuildDate><pubDate>Sun, 06 Jun 2010 14:15:51 GMT</pubDate><ttl>60</ttl><item><title>socket 编程入门教程（三）TCP原理：1、socket异常信息</title><link>http://www.cppblog.com/lf426/archive/2010/06/06/117284.html</link><dc:creator>lf426</dc:creator><author>lf426</author><pubDate>Sun, 06 Jun 2010 13:07:00 GMT</pubDate><guid>http://www.cppblog.com/lf426/archive/2010/06/06/117284.html</guid><wfw:comment>http://www.cppblog.com/lf426/comments/117284.html</wfw:comment><comments>http://www.cppblog.com/lf426/archive/2010/06/06/117284.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lf426/comments/commentRss/117284.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lf426/services/trackbacks/117284.html</trackback:ping><description><![CDATA[之所以把对异常信息的介绍放到原理之前讲，是因为由于socket本身的复杂性，导致了产生各种异常的复杂性。我们应该时刻铭记的是，sokcet本身属于系统（OS），是系统对TCP/IP的实现，也就是说，socket发出的异常信息不代表程序出错，甚至不代表系统出错，而仅仅就是代表socket本身的各种异常情况。另外一点我觉得应该强调的是：socket不是TCP/IP；TCP/IP也不是socket。socket是为广泛的协议设计的，涉及TCP/IP的内容只是socket体系中一个很小的子集；而TCP/IP就更加独立于sokcet而存在——TCP/IP是协议描述；socket是对协议理论的一种实现形式。<br>因为socket是属于系统的，所以不同的系统对于socket有着大同小异的解释，出错描述也不尽相同。在Linux中，socket的异常信息可以通过errno获得（int类型），然后可以通过函数strerror()将int转换成字符串描述；也可以通过函数perror()直接获得其描述。<br>要使用errno需要包含头文件&lt;errno.h&gt;。我建议使用errno获得int类的错误信息的一个重要原因在于，socket的异常不一定就必然导致程序终止。Bjarne Stroustrup在介绍C++异常机制的时候对C风格的异常机制有着这样的描述：（C++对于异常）的默认响应方式是终止程序。传统的反应（对于发生异常的时候）则是装糊涂，接着做下去，以期得到最好的结果（《C++程序设计语言》第14章 异常处理）。不过以我目前的水平看来，终止正在进行的程序然后再通过异常机制重新启动一个新的流程，其代价远远大于&#8220;装糊涂&#8221;的让程序继续运行下去，只要错误不是致命的，通过简单的判断和处理或许效果更佳。<br>例如，socket中就有一个很有代表性的情况，在TCP连接中，如果一方意外退出——也就是说没有通过TCP退出流程退出，比如没有运行完程序关闭掉socket而直接X掉或者Ctrl+c了。socket往往会因为recv()返回值小于0而抛出一个异常。正常断开连接的时候，recv()会通过返回0表示连接已经断开，但是大多数时候，我们并不希望因为异常的断开就导致另外一端的程序终止（想象一下如果你关掉QQ腾讯的服务器程序就终止是什么概念&#8230;&#8230;），所以我们必须处理这种情况。<br>在Linux中，远程连接异常断开（被重置）的errno代码是104，类似的，我们应该保证出现这种异常的时候程序可以继续运行。<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Filename:&nbsp;SockClass.hpp</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br>#ifndef&nbsp;SOCK_CLASS_HPP<br></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;SOCK_CLASS_HPP</span><span style="COLOR: #000000"><br><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">unistd.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">sys</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">socket.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">arpa</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">inet.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">errno.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;sockClass<br>{<br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;error_info(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;s);<br>}</span></div>
以上是头文件中的声明，下面是函数，我们这里仅仅演示处理了104错误。<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;sockClass<br>{<br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;error_info(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;s)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;err_info&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;errno;<br>&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;strerror(err_info)&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">:&nbsp;errno:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;err_info&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(err_info&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">104</span><span style="COLOR: #000000">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;exit(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br>}<br>}</span></div>
在windows中，错误代码由WSAGetLastError()获得，而无需设置errno。<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Filename:&nbsp;SockClass.hpp</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br>#ifndef&nbsp;SOCK_CLASS_HPP<br></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;SOCK_CLASS_HPP</span><span style="COLOR: #000000"><br><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">winsock2.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;sockClass<br>{<br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;error_info(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;s);<br>}</span></div>
WinSock的错误代码跟Linux中的不一样，同样的异常，WinSock的错误代码是10054。<br>并且，由于没有errno也就无从调用strerror()，我们最好自己写出详细的异常信息。<br>WinSock的详细代码信息在这里：<br><a href="http://msdn.microsoft.com/en-us/library/ms740668(v=VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms740668(v=VS.85).aspx</a><br>win32下的演示代码如下：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;sockClass<br>{<br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;error_info(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;s)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;winsock_err&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;WSAGetLastError();<br>&nbsp;&nbsp;&nbsp;&nbsp;perror(s);<br>&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">WinSock&nbsp;Error:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;winsock_err&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(winsock_err&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;WSAECONNRESET)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Connection&nbsp;reset&nbsp;by&nbsp;peer.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;exit(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br>}<br>}</span></div>
<img src ="http://www.cppblog.com/lf426/aggbug/117284.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lf426/" target="_blank">lf426</a> 2010-06-06 21:07 <a href="http://www.cppblog.com/lf426/archive/2010/06/06/117284.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用对象的成员函数引出线程，还是在线程中创建对象？</title><link>http://www.cppblog.com/lf426/archive/2010/06/05/117242.html</link><dc:creator>lf426</dc:creator><author>lf426</author><pubDate>Sat, 05 Jun 2010 13:06:00 GMT</pubDate><guid>http://www.cppblog.com/lf426/archive/2010/06/05/117242.html</guid><wfw:comment>http://www.cppblog.com/lf426/comments/117242.html</wfw:comment><comments>http://www.cppblog.com/lf426/archive/2010/06/05/117242.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lf426/comments/commentRss/117242.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lf426/services/trackbacks/117242.html</trackback:ping><description><![CDATA[还是先看一段非多线程的程序。我们用TestClass1表示在线程中创建的对象类，用TestClass2表示与创建线程的操作在同一定义域（也就是同一对{}之中的）的局部变量的对象类。<br>之所以提出TestClass2这种类，是因为在实际编程中我们会遇到这种情况：我们不可预知这个类何时创建以及创建多少；这个类的对象是一个新线程的参数。比如，在sokcet中的TCP server端就会有这种情况：如果每一个新连接的client都用创建一个新的线程去处理，我们不可预知在什么时候会有多少客户端连过来。<br>我们先观察没有多线程的时候对象的生命周期：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">windows.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;TestClass1{<br></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;x;<br></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">explicit</span><span style="COLOR: #000000">&nbsp;TestClass1(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;to_x):x(to_x)<br>&nbsp;&nbsp;&nbsp;&nbsp;{}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">TestClass1()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">destruction:&nbsp;1.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;show()&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;x&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};<br><br></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;TestClass2{<br></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pX;<br></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">explicit</span><span style="COLOR: #000000">&nbsp;TestClass2(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;to_x)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pX&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pX&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;to_x;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">TestClass2()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pX;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">destruction:&nbsp;2.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;value()&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pX;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};<br><br>DWORD&nbsp;WINAPI&nbsp;thread_func(LPVOID&nbsp;pN)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">200</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;TestClass1&nbsp;test((</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">((TestClass2</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)pN)).value());<br>&nbsp;&nbsp;&nbsp;&nbsp;test.show();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">;&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TestClass2&nbsp;n(</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread_func((LPVOID)</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">n);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">loop:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">2000</span><span style="COLOR: #000000">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">main()&nbsp;ok.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}</span></div>
这是标准的C++模式，对象的生命周期是可以预见的：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">5</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">.<br>loop:&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">.<br></span><span style="COLOR: #000000">5</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">.<br>loop:&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">.<br></span><span style="COLOR: #000000">5</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">.<br>loop:&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">.<br>main()&nbsp;ok.<br>请按任意键继续.&nbsp;.&nbsp;.</span></div>
如果我们改成线程调用：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">windows.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;TestClass1{<br></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;x;<br></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">explicit</span><span style="COLOR: #000000">&nbsp;TestClass1(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;to_x):x(to_x)<br>&nbsp;&nbsp;&nbsp;&nbsp;{}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">TestClass1()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">destruction:&nbsp;1.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;show()&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;x&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};<br><br></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;TestClass2{<br></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pX;<br></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">explicit</span><span style="COLOR: #000000">&nbsp;TestClass2(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;to_x)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pX&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pX&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;to_x;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">TestClass2()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pX;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">destruction:&nbsp;2.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;value()&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pX;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};<br><br>DWORD&nbsp;WINAPI&nbsp;thread_func(LPVOID&nbsp;pN)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">200</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;TestClass1&nbsp;test((</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">((TestClass2</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)pN)).value());<br>&nbsp;&nbsp;&nbsp;&nbsp;test.show();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">;&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TestClass2&nbsp;n(</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hThrd;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;thrdId;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hThrd&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;CreateThread(&nbsp;&nbsp;&nbsp;&nbsp;NULL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread_func,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPVOID)</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">n,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">thrdId);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">loop:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">2000</span><span style="COLOR: #000000">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">main()&nbsp;ok.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br></span></div>
可以看到函数返回了错误的值（至于为什么每次都是36我还不清楚，但是至少不是正确的数字5），这是因为在线程调用TestClass2的对象之前已经被析构的缘故。<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">loop:&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">.<br>loop:&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">.<br>loop:&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">.<br></span><span style="COLOR: #000000">36</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">.<br></span><span style="COLOR: #000000">36</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">.<br></span><span style="COLOR: #000000">36</span><span style="COLOR: #000000"><br>destruction:&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">.<br>main()&nbsp;ok.<br>请按任意键继续.&nbsp;.&nbsp;.</span></div>
所以，如果我们设想构造一个类，这个类的对象可以调用包含this的线程，那么这个对象一定不能是局部变量，或者说，我们必须在循环的{}对之前先把这些对象构造出来。这与我们的需求不符合——我们并不知道需要多少对象以及如何构造（比如构造TCP的通讯socket需要accept()接受客户端的信息），在这种情况下，我们只能在线程中去构造对象，这样的对象生命周期跟线程函数一样。<br>或者说，如果我们希望用类来封装线程，那么这些可以调用线程的对象必须是全局的。相关内容请参考本人前面的教程&#8220;初试多线程&#8221;等。 
<img src ="http://www.cppblog.com/lf426/aggbug/117242.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lf426/" target="_blank">lf426</a> 2010-06-05 21:06 <a href="http://www.cppblog.com/lf426/archive/2010/06/05/117242.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在多线程中抛出的异常出错？</title><link>http://www.cppblog.com/lf426/archive/2010/06/05/117241.html</link><dc:creator>lf426</dc:creator><author>lf426</author><pubDate>Sat, 05 Jun 2010 12:16:00 GMT</pubDate><guid>http://www.cppblog.com/lf426/archive/2010/06/05/117241.html</guid><wfw:comment>http://www.cppblog.com/lf426/comments/117241.html</wfw:comment><comments>http://www.cppblog.com/lf426/archive/2010/06/05/117241.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lf426/comments/commentRss/117241.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lf426/services/trackbacks/117241.html</trackback:ping><description><![CDATA[以下以win32平台为例。我们先看一个非多线程的程序：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">windows.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><br>DWORD&nbsp;WINAPI&nbsp;thread_func(LPVOID&nbsp;pN)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">((</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)pN);&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">\t</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ok.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">thread_func()&nbsp;done.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;n&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">{<br>&nbsp;&nbsp;&nbsp;&nbsp;thread_func((LPVOID)</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">n);<br>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">2000</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;s)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;s&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">main()&nbsp;done.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}</span></div>
可以看到，函数thread_func()可以正确的抛出异常并被main()的catch捕捉。但是，如果用一个新线程来运行thread_func()会出现什么情况呢？<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">windows.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><br>DWORD&nbsp;WINAPI&nbsp;thread_func(LPVOID&nbsp;pN)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">((</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)pN);&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">\t</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ok.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">thread_func()&nbsp;done.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hThrd;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;thrdId;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;n&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">{<br>&nbsp;&nbsp;&nbsp;&nbsp;hThrd&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;CreateThread(&nbsp;&nbsp;&nbsp;&nbsp;NULL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread_func,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPVOID)</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">n,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">thrdId);<br>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">2000</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;s)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;s&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">main()&nbsp;done.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}</span></div>
很不幸，这个程序编译的时候是可以通过的，但是运行时出错：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000"><br><br>This&nbsp;application&nbsp;has&nbsp;requested&nbsp;the&nbsp;Runtime&nbsp;to&nbsp;terminate&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;an&nbsp;unusual&nbsp;way.<br>Please&nbsp;contact&nbsp;the&nbsp;application</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">s&nbsp;support&nbsp;team&nbsp;for&nbsp;more&nbsp;information.</span><span style="COLOR: #000000"><br></span><span style="COLOR: #000000">请按任意键继续.&nbsp;.&nbsp;.</span></div>
而且同时会有一个运行时错误的提示。事实上，这个错误提示意味着程序在没有发现try{}的时候看到了throw。<br>通过试验，我发现系统（这里是win32）不能将CreateThread()所产生的线程归结到try{}中。更加严重的情况是，即使用一个函数囊括了整个程序，然后try这个函数，其他线程依然脱离了这个try。<br>所以，一个解决方法是，凡是遇到新的线程，必须在新线程中重新写异常处理。不然，就如google代码标准里所说的那样，不使用C++的异常机制。毕竟C++没有定义多线程的标准，所以也就无从说起多线程中异常处理的标准。<br>最后附上在新线程写异常处理的参考：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">windows.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><br>DWORD&nbsp;WINAPI&nbsp;thread_func(LPVOID&nbsp;pN)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">((</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)pN);&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">\t</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ok.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;s)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;s&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">thread_func()&nbsp;done.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hThrd;<br>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;thrdId;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;n&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;hThrd&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;CreateThread(&nbsp;&nbsp;&nbsp;&nbsp;NULL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread_func,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPVOID)</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">n,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">thrdId);<br>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">2000</span><span style="COLOR: #000000">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">main()&nbsp;done.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}</span></div>
<img src ="http://www.cppblog.com/lf426/aggbug/117241.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lf426/" target="_blank">lf426</a> 2010-06-05 20:16 <a href="http://www.cppblog.com/lf426/archive/2010/06/05/117241.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>socket 编程入门教程（二）win32下使用socket：WinSock</title><link>http://www.cppblog.com/lf426/archive/2010/06/03/117074.html</link><dc:creator>lf426</dc:creator><author>lf426</author><pubDate>Thu, 03 Jun 2010 02:37:00 GMT</pubDate><guid>http://www.cppblog.com/lf426/archive/2010/06/03/117074.html</guid><wfw:comment>http://www.cppblog.com/lf426/comments/117074.html</wfw:comment><comments>http://www.cppblog.com/lf426/archive/2010/06/03/117074.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lf426/comments/commentRss/117074.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lf426/services/trackbacks/117074.html</trackback:ping><description><![CDATA[学习socket最好能有两台以上联网的电脑，以及能获得公网IP的网络接入方式。两年前，我主要使用的是一台win2k3和Debain Linux双系统的电脑，例外有台99年的老机器装着win98，而且没有装VC，测试相当的麻烦。现在买了笔记本，使用的是Vista的win32环境（32位），可以直接和老电脑的Linux联网进行测试。另外，网络环境也换成了电信的ADSL，贵了很多，为的就是能有一个公网IP。接下来的教程我会兼顾winsock的代码，这主要是因为winsock本身对socket几乎是兼容的。所以，这里有必要先说明在VC环境中使用socket的一些简单设置，以及与Linux环境下的细微差别。<br>我的VC环境依然是2008 Express，在写这篇教程的时候，微软已经发布了VC 2010，目前在微软的官方主页，提供了VC 2010的下载，同时保留着VC 2008的下载。<br>我们在VC中建立一个控制台的空项目：<br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/lf426/p01.jpg" width=818 height=621><br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/lf426/p02.jpg" width=634 height=539><br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/lf426/p03.jpg" width=621 height=538><br>我们着手构建自己的第一个winsock程序。<br>首先win32下与Linux下的socket API需要包含不同的头文件。<br>在Linux下是这些：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">unistd.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">sys</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">socket.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">arpa</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">inet.h</span><span style="COLOR: #000000">&gt;</span></div>
win32下的winsock有多个版本，我所找到的资料中，老的版本是：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">winsock.h</span><span style="COLOR: #000000">&gt;</span></div>
与之对应的需要的链接库为：<br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/lf426/p04.jpg" width=422 height=398><br><br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/lf426/p05.jpg" width=778 height=644><br>这可能可以兼容非常古老的版本中的winsock，比如win98，而微软官方所推荐的是：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">winsock2.h</span><span style="COLOR: #000000">&gt;</span></div>
链接库是：ws2_32.lib，这样就可以使用高版本的winsock。<br>那么，什么是winsock的版本？这就涉及到winsock的初始化函数WSAStartup：<br><a href="http://msdn.microsoft.com/en-us/library/ms742213(v=VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms742213(v=VS.85).aspx</a><br>上面是微软的官方说明，我这里构建一个简单的类，希望每次使用的时候引入一个类对象就可以了。<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;WinsockAPI{<br></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br>&nbsp;&nbsp;&nbsp;&nbsp;WSADATA&nbsp;wsaData;<br></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br>&nbsp;&nbsp;&nbsp;&nbsp;WinsockAPI(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;low_byte&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;high_byte&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">WinsockAPI();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;showVersion()&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">;<br>};</span></div>
WSADATA是记录着winsock信息的结构。<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008000">//</span><span style="COLOR: #008000">class&nbsp;WinsockAPI</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br>WinsockAPI::WinsockAPI(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;low_byte,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;high_byte)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WORD&nbsp;wVersionRequested&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;MAKEWORD(low_byte,&nbsp;high_byte);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;wsa_startup_err&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;WSAStartup(wVersionRequested,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">wsaData);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(wsa_startup_err&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">WSAStartup()&nbsp;failed.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000">&nbsp;wsa_startup_err;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br>WinsockAPI::</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">WinsockAPI()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;WSACleanup();<br>}<br><br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;WinsockAPI::showVersion()&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">The&nbsp;version&nbsp;of&nbsp;Winsock.dll&nbsp;is&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">(LOBYTE(wsaData.wVersion))&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">(HIBYTE(wsaData.wVersion))&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br>}</span></div>
首先，宏MAKEWORD()将两个int转换为winsock形式的版本号，我这里默认是是2.2，就只需要MAKEWORD(2, 2)，如果是老版本的，最低应该是1.0。WSAStartup()将winsock的初始化信息写入一个WSADATA结构（我们这里的wsaData），如果成功返回0，失败将返回一个int的错误代码。这个错误代码直接表示了错误信息，微软官方建议不使用winsock的通用异常信息获取函数WSAGetLastError()获取WSAStartup()的错误信息，这可能是因为如果WSAStartup()失败，那么winsock的错误信息不一定能够正确的构建出来的缘故。<br>最后，winsock结束后用WSACleanup()清理。<br>因为socket本身的复杂性，异常信息提示非常重要。WSAGetLastError()的官方说明如下：<br><a href="http://msdn.microsoft.com/en-us/library/ms741580(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms741580(VS.85).aspx</a><br>错误代码所反馈的信息查询在这里：<br><a href="http://msdn.microsoft.com/en-us/library/ms740668(v=VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms740668(v=VS.85).aspx</a><br>最后，需要注意的问题是，因为socket是构建在UNIX系统下的（BSD socket是当今所有socket的基础），所以socket很好的利用了UNIX体系&#8220;一切都是文件&#8221;的性质，每个socket本身也就是一个UNIX文件描述符，因此，Linux下的socket是用关闭文件的函数close()关闭的。但是win32下没这个性质，所以winsock是另外一种抽象，但是好在同样用int作为描述符，关闭需要专门为winsock定做的函数closesocket()。<br>下篇文章重写了TCP Server的代码（类的抽象和构造也重新写了，将在下一章解释），作为winsock使用的演示。
<img src ="http://www.cppblog.com/lf426/aggbug/117074.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lf426/" target="_blank">lf426</a> 2010-06-03 10:37 <a href="http://www.cppblog.com/lf426/archive/2010/06/03/117074.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Microsoft Visual C++ 2008 发布程序的部署问题</title><link>http://www.cppblog.com/lf426/archive/2008/04/12/46885.html</link><dc:creator>lf426</dc:creator><author>lf426</author><pubDate>Fri, 11 Apr 2008 17:51:00 GMT</pubDate><guid>http://www.cppblog.com/lf426/archive/2008/04/12/46885.html</guid><wfw:comment>http://www.cppblog.com/lf426/comments/46885.html</wfw:comment><comments>http://www.cppblog.com/lf426/archive/2008/04/12/46885.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.cppblog.com/lf426/comments/commentRss/46885.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lf426/services/trackbacks/46885.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; VC2005和VC2008编译出来的程序放到别人的电脑上为什么有可能无法运行呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个问题无数人在问，但是很遗憾，没有人给出完整的解释和完美的解决方案。其实我也只有一台电脑，而且装了VC了，这个问题必须要台没有装这类软件的电脑才容易去分析。感谢那些为了测试我小程序的朋友，是你们一次次在如此恶劣的网络速度下收取我一次次修改的dll包和部署文件，才让这个问题的完美解决方案浮出水面。这里就把我的经验给大家分享吧。<br><br>1：Microsoft Visual C++ 2008 Express Edition可以发布软件吗？<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 能！<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 很多人说，因为是Express版，不是Studio，所以只是用来练习语言的，不能发布软件——错！<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 除了没有MFC和ATL，基本上跟 .net 版本是一样的。发布出来的，是完整的可执行文件。<br><br>2：VC 2008 (2005) 发布出来的程序必须附带上他们特定的dll文件吗？<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不一定。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果目标系统是个经常升级的系统，微软已经为其打上了所需要的dll文件补丁了，不需要在软件包里面附加特定的dll文件。特别在Vista系统中，你更是不需要VC8和VC9的dll文件。但是在一些老版本的系统中，这些文件就是必须的。<br><br>3：VC2008和VC2005特定的dll文件是哪些？<br><br>VC8: msvcm80.dll, msvcp80.dll, msvcr80.dll<br>VC9: msvcm90.dll, msvcp90.dll, msvcr90.dll<br><br>4：如何部署文件？<br><br>首先，请选择release版本；在生成可执行文件（exe文件）的时候，会得到相应的部署文件（manifest文件）。<br>比如，得到a.exe文件，就会同时生成a.exe.intermediate.manifest文件。请将这2个文件放在同一文件夹下。<br>然后，你需要VC8和VC9的部署文件：Microsoft.VC80.CRT.manifest和Microsoft.VC90.CRT.manifest。<br>请到你的VC安装目录下寻找，比如：<br>C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT<br>我这里也把2个部署文件直接贴出来，没装的直接用就是了：<br>Microsoft.VC80.CRT.manifest<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"&nbsp;standalone="yes"</span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">assembly&nbsp;</span><span style="COLOR: #ff0000">xmlns</span><span style="COLOR: #0000ff">="urn:schemas-microsoft-com:asm.v1"</span><span style="COLOR: #ff0000">&nbsp;manifestVersion</span><span style="COLOR: #0000ff">="1.0"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">noInheritable</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">noInheritable</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">assemblyIdentity&nbsp;</span><span style="COLOR: #ff0000">type</span><span style="COLOR: #0000ff">="win32"</span><span style="COLOR: #ff0000">&nbsp;name</span><span style="COLOR: #0000ff">="Microsoft.VC80.CRT"</span><span style="COLOR: #ff0000">&nbsp;version</span><span style="COLOR: #0000ff">="8.0.50727.762"</span><span style="COLOR: #ff0000">&nbsp;processorArchitecture</span><span style="COLOR: #0000ff">="x86"</span><span style="COLOR: #ff0000">&nbsp;publicKeyToken</span><span style="COLOR: #0000ff">="1fc8b3b9a1e18e3b"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">assemblyIdentity</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">file&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="msvcr80.dll"</span><span style="COLOR: #ff0000">&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">file&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="msvcp80.dll"</span><span style="COLOR: #ff0000">&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">file&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="msvcm80.dll"</span><span style="COLOR: #ff0000">&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">assembly</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span></div>
Microsoft.VC90.CRT.manifest<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"&nbsp;standalone="yes"</span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008000">&lt;!--</span><span style="COLOR: #008000">&nbsp;Copyright&nbsp;(c)&nbsp;Microsoft&nbsp;Corporation.&nbsp;&nbsp;All&nbsp;rights&nbsp;reserved.&nbsp;</span><span style="COLOR: #008000">--&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">assembly&nbsp;</span><span style="COLOR: #ff0000">xmlns</span><span style="COLOR: #0000ff">="urn:schemas-microsoft-com:asm.v1"</span><span style="COLOR: #ff0000">&nbsp;manifestVersion</span><span style="COLOR: #0000ff">="1.0"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">noInheritable</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">assemblyIdentity<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff0000">type</span><span style="COLOR: #0000ff">="win32"</span><span style="COLOR: #ff0000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name</span><span style="COLOR: #0000ff">="Microsoft.VC90.CRT"</span><span style="COLOR: #ff0000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;version</span><span style="COLOR: #0000ff">="9.0.21022.8"</span><span style="COLOR: #ff0000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processorArchitecture</span><span style="COLOR: #0000ff">="x86"</span><span style="COLOR: #ff0000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publicKeyToken</span><span style="COLOR: #0000ff">="1fc8b3b9a1e18e3b"</span><span style="COLOR: #ff0000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">file&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="msvcr90.dll"</span><span style="COLOR: #ff0000">&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">file&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="msvcp90.dll"</span><span style="COLOR: #ff0000">&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">file&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="msvcm90.dll"</span><span style="COLOR: #ff0000">&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">assembly</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span></div>
然后将VC8的3个dll以及这个manifest装到一个文件夹里，并将文件夹命名为Microsoft.VC80.CRT。<br>同样将VC9的3个dll以及这个manifest装到一个文件夹里，并将文件夹命名为Microsoft.VC90.CRT。<br>将这2个文件夹放到与exe文件（及其部署文件）所在目录下就OK了。<br>至于为什么VC9编译的程序要用VC8的dll，大家可以看看我例程部署文件：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml&nbsp;version='1.0'&nbsp;encoding='UTF-8'&nbsp;standalone='yes'</span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">assembly&nbsp;</span><span style="COLOR: #ff0000">xmlns</span><span style="COLOR: #0000ff">='urn:schemas-microsoft-com:asm.v1'&nbsp;</span><span style="COLOR: #ff0000">manifestVersion</span><span style="COLOR: #0000ff">='1.0'&gt;<br>&nbsp;&nbsp;</span><span style="COLOR: #ff0000">&lt;trustInfo&nbsp;xmlns</span><span style="COLOR: #0000ff">="urn:schemas-microsoft-com:asm.v3"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">security</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">requestedPrivileges</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">requestedExecutionLevel&nbsp;</span><span style="COLOR: #ff0000">level</span><span style="COLOR: #0000ff">='asInvoker'&nbsp;</span><span style="COLOR: #ff0000">uiAccess</span><span style="COLOR: #0000ff">='false'&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">requestedPrivileges</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">security</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">trustInfo</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">dependency</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">dependentAssembly</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">assemblyIdentity&nbsp;</span><span style="COLOR: #ff0000">type</span><span style="COLOR: #0000ff">='win32'&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">='Microsoft.VC90.CRT'&nbsp;</span><span style="COLOR: #ff0000">version</span><span style="COLOR: #0000ff">='9.0.21022.8'&nbsp;</span><span style="COLOR: #ff0000">processorArchitecture</span><span style="COLOR: #0000ff">='x86'&nbsp;</span><span style="COLOR: #ff0000">publicKeyToken</span><span style="COLOR: #0000ff">='1fc8b3b9a1e18e3b'&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">dependentAssembly</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">dependency</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">dependency</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">dependentAssembly</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">assemblyIdentity&nbsp;</span><span style="COLOR: #ff0000">type</span><span style="COLOR: #0000ff">='win32'&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">='Microsoft.VC80.CRT'&nbsp;</span><span style="COLOR: #ff0000">version</span><span style="COLOR: #0000ff">='8.0.50727.762'&nbsp;</span><span style="COLOR: #ff0000">processorArchitecture</span><span style="COLOR: #0000ff">='x86'&nbsp;</span><span style="COLOR: #ff0000">publicKeyToken</span><span style="COLOR: #0000ff">='1fc8b3b9a1e18e3b'&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">dependentAssembly</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">dependency</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">assembly</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span></div>
VC 2008生成出来就需要VC90和VC80的CRT，我们能有什么脾气呢&#8230;&#8230;<br>也就是说，还别管你exe文件多大，要保证正常运行，我们需要首先拷贝这8个文件&#8230;&#8230;<br>MinGW(gcc)编译的就没这些麻烦。所以，我现在都是用两个编译器编译两个exe以供发布了。
<img src ="http://www.cppblog.com/lf426/aggbug/46885.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lf426/" target="_blank">lf426</a> 2008-04-12 01:51 <a href="http://www.cppblog.com/lf426/archive/2008/04/12/46885.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Microsoft Visual C++ 2008 Express Edition下为exe程序添加图标</title><link>http://www.cppblog.com/lf426/archive/2008/03/31/45833.html</link><dc:creator>lf426</dc:creator><author>lf426</author><pubDate>Mon, 31 Mar 2008 11:24:00 GMT</pubDate><guid>http://www.cppblog.com/lf426/archive/2008/03/31/45833.html</guid><wfw:comment>http://www.cppblog.com/lf426/comments/45833.html</wfw:comment><comments>http://www.cppblog.com/lf426/archive/2008/03/31/45833.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/lf426/comments/commentRss/45833.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lf426/services/trackbacks/45833.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为想到第10章的内容比较繁杂，所以想给大家一个完整的演示程序以及源代码。那个难看的默认可执行程序的图标实在让我忍受不了了，VC Express貌似又没有给提供VS那样的给exe文件添加图标的功能，所以，我从VC6来找解决方案。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 结果比我想像简单得多！<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我用VC6导入一个ico文件，并得到了它的资源文件Script1.rc。嘿嘿，C风格的，那就不客气的分析了。原来要用到VC6的3个头文件：resource.h，afxres.h和WINRES.H。我把rc文件和3个头文件，以及ico图标文件都导入VC 2008 Express的项目中，居然就无情的成功了！看来Express仍然不愧是VS的阉割版，其实就是少了点材料，基本能力还是在的。^^<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最后我干脆把3个h文件合并到rc文件中了，并且给它起个好记的名字：icon.rc，并做了简单的修改。现在使用起来就更简单了：<br>1、将icon.rc导入VC2008的资源（Resource Files）中；<br>2、将ico文件更名为logo.ico并放到项目文件夹下（即存放cpp和h文件的文件夹）；<br>3、编译，OK了！<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我在演示程序中包含了这个好用的icon.rc，有兴趣的朋友可以直接下载来使用了，您甚至都不需要装VC6。下载地址：（在rc文件夹下）<br><a href="http://www.fs2you.com/zh-cn/files/62f0acf0-ff11-11dc-a4f4-0014221b798a/">http://www.fs2you.com/zh-cn/files/62f0acf0-ff11-11dc-a4f4-0014221b798a/</a>
<img src ="http://www.cppblog.com/lf426/aggbug/45833.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lf426/" target="_blank">lf426</a> 2008-03-31 19:24 <a href="http://www.cppblog.com/lf426/archive/2008/03/31/45833.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>