﻿<?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++博客-&lt;font color="#ff8000"&gt;&amp;nbsp&amp;nbsp&amp;nbspC++&amp;nbsp技术中心&lt;/font&gt;-随笔分类-Windows 编程</title><link>http://www.cppblog.com/API/category/16121.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 31 Jul 2015 23:42:59 GMT</lastBuildDate><pubDate>Fri, 31 Jul 2015 23:42:59 GMT</pubDate><ttl>60</ttl><item><title>异常和异常处理（windows平台）</title><link>http://www.cppblog.com/API/archive/2014/11/26/208965.html</link><dc:creator>C++技术中心</dc:creator><author>C++技术中心</author><pubDate>Wed, 26 Nov 2014 07:12:00 GMT</pubDate><guid>http://www.cppblog.com/API/archive/2014/11/26/208965.html</guid><wfw:comment>http://www.cppblog.com/API/comments/208965.html</wfw:comment><comments>http://www.cppblog.com/API/archive/2014/11/26/208965.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/API/comments/commentRss/208965.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/API/services/trackbacks/208965.html</trackback:ping><description><![CDATA[<div>【翻译】异常和异常处理（windows平台）</div><div>翻译的不好，莫怪。</div><div>原文地址： http://crashrpt.sourceforge.net/docs/html/exception_handling.html#getting_exception_context</div><div>About Exceptions and Exception Handling</div><div></div><div>About Exception</div><div></div><div>当程序遇到一个异常或一个严重的错误时，通常意味着它不能继续正常运行并且需要停止执行。</div><div>例如，当遇到下列情况时，程序会出现异常：</div><div>&nbsp; 程序访问一个不可用的内存地址（例如，NULL指针）；</div><div>l 无限递归导致的栈溢出；</div><div>l 向一个较小的缓冲区写入较大块的数据；</div><div>l 类的纯虚函数被调用；</div><div>l 申请内存失败（内存空间不足）；</div><div>l 一个非法的参数被传递给C++函数；</div><div>l C运行时库检测到一个错误并且需要程序终止执行。</div><div>&nbsp;</div><div>有两种不同性质的异常：结构化异常(Structured Exception Handling, SEH)和类型化的C++异常。</div><div>SEH是为C语言设计的，但是他们也能够被用于C++。SEH异常由__try{}__except(){}结构来处理。SEH是VC++编译器特有的，因此如果你想要编写可移植的代码，就不应当使用SEH。</div><div>C++中类型化的异常是由try{}catch(){}结构处理的。例如（例子来自这里http://www.cplusplus.com/doc/tutorial/exceptions/）：</div><div></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&nbsp;#include&nbsp;&lt;iostream&gt;<br />&nbsp;<span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br />&nbsp;&nbsp;<br />&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;20;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;e){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;"An&nbsp;exception&nbsp;occrred.&nbsp;Exception&nbsp;Nr.&nbsp;"&nbsp;&lt;&lt;&nbsp;e&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />&nbsp;}</div></div><div>&nbsp;</div><div>结构化异常处理</div><div></div><div>当发生一个SEH异常时，你通常会看到一个意图向微软发送错误报告的弹出窗口。</div><div>你可以使用RaiseException()函数自己产生一个SEH异常。</div><div>你可以在你的代码中使用__try{}__except(Expression){}结构来捕获SEH异常。程序中的main()函数被这样的结构保护，因此默认地，所有未被处理的SEH异常都会被捕获。</div><div>例如：</div><div></div><div>&nbsp;<span style="background-color: #eeeeee; font-size: 13px;">#include&nbsp;</span><span style="background-color: #eeeeee; font-size: 13px;">&lt;</span><span style="background-color: #eeeeee; font-size: 13px;">Windows.h</span><span style="background-color: #eeeeee; font-size: 13px;">&gt;</span></div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all">&nbsp;&nbsp;<br />&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;*p&nbsp;=&nbsp;NULL;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;pointer&nbsp;to&nbsp;NULL</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__try{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Guarded&nbsp;code</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*p&nbsp;=&nbsp;13;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;causes&nbsp;an&nbsp;access&nbsp;violation&nbsp;exception;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__except(EXCEPTION_EXECUTE_HANDLER){&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Here&nbsp;is&nbsp;exception&nbsp;filter&nbsp;expression<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Here&nbsp;is&nbsp;exception&nbsp;handler<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Terminate&nbsp;program</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExitProcess(1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />&nbsp;}</div><div></div><div>&nbsp;</div><div>&nbsp;</div><div>每一个SEH异常都有一个与其相关联的异常码（exception code）。你可以使用GetExceptionCode()函数来获取异常码。你可以通过GetExceptionInformation()来获取异常信息。为了使用这些函数，你通常会像下面示例中一样定制自己的exception filter。</div><div>下面的例子说明了如何使用SEH exception filter。</div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><br />&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;seh_filter(unsigned&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;code,&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;_EXCEPTION_POINTERS&nbsp;*ep){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Generate&nbsp;error&nbsp;report<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Execute&nbsp;exception&nbsp;handler</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;EXCEPTION_EXECUTE_HANDLER;<br />&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__try{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;..&nbsp;some&nbsp;buggy&nbsp;code&nbsp;here</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__except(seh_filter(GetExceptionCode(),&nbsp;GetExceptionInformation())){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Terminate&nbsp;program</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExitProcess(1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />&nbsp;}</div></div><div></div><div>&nbsp;</div><div>&nbsp;</div><div>__try{}__exception(){}结构是面向C语言的，但是，你可以将一个SEH异常重定向到C++异常，并且你可以像处理C++异常一样处理它。我们可以使用C++运行时库中的_set_se_translator()函数来实现。</div><div>看一个MSDN中的例子（译者注：运行此例子需打开/EHa编译选项）：</div><div></div><div>&nbsp;<span style="background-color: #eeeeee; font-size: 13px;">&nbsp;&nbsp;#include&nbsp;</span><span style="background-color: #eeeeee; font-size: 13px;">&lt;</span><span style="background-color: #eeeeee; font-size: 13px;">cstdio</span><span style="background-color: #eeeeee; font-size: 13px;">&gt;</span></div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all">&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;windows.h&gt;<br />&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;eh.h&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;SEFunc();<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;trans_func(unsigned&nbsp;<span style="color: #0000FF; ">int</span>,&nbsp;EXCEPTION_POINTERS&nbsp;*);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;SE_Exception{<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nSE;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SE_Exception(){}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SE_Exception(unsigned&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;n)&nbsp;:&nbsp;nSE(n){}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~SE_Exception()&nbsp;{}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;getSeNumber(){&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;nSE;&nbsp;}<br />&nbsp;&nbsp;&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">void</span>){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_set_se_translator(trans_func);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SEFunc();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">catch</span>(SE_Exception&nbsp;e){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Caught&nbsp;a&nbsp;__try&nbsp;exception&nbsp;with&nbsp;SE_Exception.\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;SEFunc(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__try{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;x,&nbsp;y=0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;=&nbsp;5&nbsp;/&nbsp;y;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__finally{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("In&nbsp;finally\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;trans_func(unsigned&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;u,&nbsp;EXCEPTION_POINTERS*&nbsp;pExp){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("In&nbsp;trans_func.\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;SE_Exception();<br />&nbsp;&nbsp;&nbsp;}</div><div></div><div>&nbsp;</div><div>&nbsp;</div><div>你可能忘记对一些潜在的错误代码使用__try{}__catch(Expression){}结构进行保护，而这些代码可能会产生异常，但是这个异常却没有被你的程序所处理。不用担心，这个未被处理的SEH异常能够被unhandled Exception filter所捕获，我们可以使用SetUnhandledExceptionFilter()函数设置top-levelunhandled exception filter。</div><div>异常信息（异常发生时的CPU状态）通过EXCEPTION_POINTERS被传递给exception handler。</div><div>例如：</div><div></div><div>&nbsp;<span style="background-color: #eeeeee; font-size: 13px;">&nbsp;&nbsp;</span><span style="font-size: 13px; color: #008000;">//</span><span style="font-size: 13px; color: #008000;">&nbsp;crt_settrans.cpp</span></div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;compile&nbsp;with:&nbsp;/EHa</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;LONG&nbsp;WINAPI&nbsp;MyUnhandledExceptionFilter(PEXCEPTION_POINTERS&nbsp;pExceptionPtrs){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Do&nbsp;something,&nbsp;for&nbsp;example&nbsp;generate&nbsp;error&nbsp;report<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">..<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Execute&nbsp;default&nbsp;exception&nbsp;handler&nbsp;next</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;EXCEPTION_EXECUTE_HANDLER;<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;..&nbsp;some&nbsp;unsafe&nbsp;code&nbsp;here</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;}</div><div></div><div>&nbsp;</div><div>&nbsp;</div><div>top-level SEH exception handler对进程中的每个线程都起作用，因此在你的main()函数开头调用一次就够了。</div><div>top-level SEH exception handler在发生异常的线程的上下文中被调用。这会影响异常处理函数从异常中恢复的能力。</div><div>如果你的异常处理函数位于一个DLL中，那么在使用SetUnhandledExceptionFilter()函数时就要小心了。如果你的函数在程序崩溃时还未被加载，这种行为是不可预测的。</div><div>向量化异常处理（Vectored Exception Handling）</div><div></div><div>向量化异常处理(VEH)是结构化异常处理的一个扩展，它在Windows XP中被引入。</div><div>你可以使用AddVectoredExceptionHandler()函数添加一个向量化异常处理器，VEH的缺点是它只能用在WinXP及其以后的版本，因此需要在运行时检查AddVectoredExceptionHandler()函数是否存在。</div><div>要移除先前安装的异常处理器，可以使用RemoveVectoredExceptionHandler()函数。</div><div>VEH允许查看或处理应用程序中所有的异常。为了保持后向兼容，当程序中的某些部分发生SEH异常时，系统依次调用已安装的VEH处理器，直到它找到有用的SEH处理器。</div><div>VEH的一个优点是能够链接异常处理器(chain exception handlers)，因此如果有人在你之前安装了向量化异常处理器，你仍然能截获这些异常。</div><div>当你需要像调试器一样监事所有的异常时，使用VEH是很合适的。问题是你需要决定哪个异常需要处理，哪个异常需要跳过。 In program's code, some exceptions may be intentionally guarded by __try{}__except(){} construction, and handling such exceptions in VEH and not passing it to frame-based SEH handler, you may introduce bugs into application logics.</div><div>VEH目前没有被CrashRpt所使用。SetUnhandledExceptionFilter()更加适用，因为它是top-level SEH处理器。如果没有人处理异常，top-level SEH处理器就会被调用，并且你不用决定是否要处理这个异常。</div><div>CRT 错误处理</div><div></div><div>除了SEH异常和C++类型化异常，C运行库(C runtime libraries, CRT)也提供它自己的错误处理机制，在你的程序中也应该考虑使用它。</div><div>当CRT遇到一个未被处理的C++类型化异常时，它会调用terminate()函数。如果你想拦截这个调用并提供合适的行为，你应该使用set_terminate()函数设置错误处理器(error hanlder)。例如：</div><div></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&nbsp; &nbsp;#include&nbsp;&lt;iostream&gt;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;my_terminate_handler()<br />&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Abnormal&nbsp;program&nbsp;termination&nbsp;(terminate()&nbsp;function&nbsp;was&nbsp;called)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Do&nbsp;something&nbsp;here<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Finally,&nbsp;terminate&nbsp;program</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"terminate.\n";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main()<br />&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_terminate(my_terminate_handler);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;terminate();<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />&nbsp;&nbsp;&nbsp;}</div></div><div></div><div>&nbsp;</div><div>&nbsp;</div><div>Note：在多线程环境中，每个线程维护各自的unexpected和terminate函数。每个新线程需要安装自己的unexpected和terminate函数。因此，每个线程负责自己的unexpected和terminate处理器。</div><div>&nbsp;</div><div>使用_set_purecall_handler()函数来处理纯虚函数调用。这个函数可以用于VC++2003及其后续版本。这个函数可以用于一个进程中的所有线程。例如（来源于MSDN）：</div><div></div><div>&nbsp;&nbsp;<span style="background-color: #eeeeee; font-size: 13px;">&nbsp;</span><span style="font-size: 13px; color: #008000;">//</span><span style="font-size: 13px; color: #008000;">&nbsp;compile&nbsp;with:&nbsp;/EHa</span></div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;_set_purecall_handler.cpp<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;compile&nbsp;with:&nbsp;/W1</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;tchar.h&gt;<br />&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;stdio.h&gt;<br />&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;stdlib.h&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;CDerived;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;CBase{<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CBase(CDerived&nbsp;*derived):&nbsp;m_pDerived(derived)&nbsp;{};<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~CBase();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;function(<span style="color: #0000FF; ">void</span>)&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDerived&nbsp;*&nbsp;m_pDerived;<br />&nbsp;&nbsp;&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;CDerived&nbsp;:&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;CBase{<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDerived()&nbsp;:&nbsp;CBase(<span style="color: #0000FF; ">this</span>)&nbsp;{};&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;C4355</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">virtual</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;function(<span style="color: #0000FF; ">void</span>)&nbsp;{};<br />&nbsp;&nbsp;&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;CBase::~CBase(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pDerived&nbsp;-&gt;&nbsp;function();<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;myPurecallHandler(<span style="color: #0000FF; ">void</span>){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("In&nbsp;_purecall_handler.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;_tmain(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;_TCHAR*&nbsp;argv[]){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">_set_purecall_handler(myPurecallHandler);</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDerived&nbsp;myDerived;<br />&nbsp;&nbsp;&nbsp;}</div><div></div><div>&nbsp;</div><div>&nbsp;</div><div>使用_set_new_handler()函数处理内存分配失败。这个函数能够用于VC++2003及其后续版本。这个函数可以用于一个进程中的所有线程。也可以考虑使用_set_new_mode()函数来为malloc()函数定义错误时的行为。例如（来自MSDN）：</div><div></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;crt_settrans.cpp</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;#include&nbsp;&lt;<span style="color: #0000FF; ">new</span>.h&gt;<br />&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;handle_program_memory_depletion(&nbsp;size_t&nbsp;){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Your&nbsp;code</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;}<br />&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main(&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_set_new_handler(&nbsp;handle_program_memory_depletion&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;*pi&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<span style="color: #0000FF; ">int</span>[BIG_NUMBER];<br />&nbsp;&nbsp;}</div></div><div></div><div>&nbsp;</div><div>&nbsp;</div><div>在VC++2003中，你能够使用_set_security_error_handler()函数来处理缓冲区溢出错误。这个函数已经被废弃，并且从之后VC++版本的CRT中移除。</div><div>当系统函数调用检测到非法的参数时，会使用_set_invalid_parameter_handler()函数来处理这种情况。这个函数能够用于VC++2005及其以后的版本。这个函数可用于进程中的所有线程。</div><div>例子（来源于MSDN）：</div><div></div><div>&nbsp;&nbsp;<span style="background-color: #eeeeee; font-size: 13px;">&nbsp;</span><span style="font-size: 13px; color: #008000;">//</span><span style="font-size: 13px; color: #008000;">&nbsp;compile&nbsp;with:&nbsp;/Zi&nbsp;/MTd</span></div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all">&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;stdio.h&gt;<br />&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;stdlib.h&gt;<br />&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;crtdbg.h&gt;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;For&nbsp;_CrtSetReportMode</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;myInvalidParameterHandler(<span style="color: #0000FF; ">const</span>&nbsp;wchar_t*&nbsp;expression,<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;<span style="color: #0000FF; ">const</span>&nbsp;wchar_t*&nbsp;function,<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;<span style="color: #0000FF; ">const</span>&nbsp;wchar_t*&nbsp;file,<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;unsigned&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;line,<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;uintptr_t&nbsp;pReserved){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wprintf(L"Invalid&nbsp;parameter&nbsp;detected&nbsp;in&nbsp;function&nbsp;%s."<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;L"&nbsp;File:&nbsp;%s&nbsp;Line:&nbsp;%d\n",&nbsp;function,&nbsp;file,&nbsp;line);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wprintf(L"Expression:&nbsp;%s\n",&nbsp;expression);<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main(&nbsp;){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;formatString;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_invalid_parameter_handler&nbsp;oldHandler,&nbsp;newHandler;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newHandler&nbsp;=&nbsp;myInvalidParameterHandler;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oldHandler&nbsp;=&nbsp;_set_invalid_parameter_handler(newHandler);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Disable&nbsp;the&nbsp;message&nbsp;box&nbsp;for&nbsp;assertions.</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_CrtSetReportMode(_CRT_ASSERT,&nbsp;0);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Call&nbsp;printf_s&nbsp;with&nbsp;invalid&nbsp;parameters.</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatString&nbsp;=&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(formatString);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />&nbsp;&nbsp;&nbsp;}</div><div></div><div>&nbsp;</div><div>&nbsp;</div><div>C++信号处理C++ Singal Handling</div><div></div><div>C++提供了被称为信号的中断机制。你可以使用signal()函数处理信号。</div><div>Visual C++提供了6中类型的信号：</div><div>l SIGABRT Abnormal termination</div><div>l SIGFPE Floating-point error</div><div>l SIGILL Illegal instruction</div><div>l SIGINT CTRL+C signal</div><div>l SIGSEGV Illegal storage access</div><div>l SIGTERM</div><div>MSDN中说SIGILL, SIGSEGV,和SIGTERM are not generated under Windows NT并且与ANSI相兼容。但是，如果你在主线程中设置SIGSEGV signal handler，CRT将会调用它，而不是调用SetUnhandledExceptionFilter()函数设置的SHE exception handler，全局变量_pxcptinfoptrs中包含了指向异常信息的指针。</div><div>_pxcptinfoptrs也会被用于SIGFPE handler中，而在所有其他的signal handlers中，它将会被设为NULL。</div><div>当一个floating point 错误发生时，例如除零错，CRT将调用SIGFPE signal handler。然而，默认情况下，不会产生float point 异常，取而代之的是，将会产生一个NaN或无穷大的数作为这种浮点数运算的结果。可以使用_controlfp_s()函数使得编译器能够产生floating point异常。</div><div>使用raise()函数，你可以人工地产生所有的6中信号。例如：</div><div></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&nbsp; &nbsp;#include&nbsp;&lt;cstdlib&gt;<br />&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;csignal&gt;<br />&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;iostream&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;sigabrt_handler(<span style="color: #0000FF; ">int</span>){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Caught&nbsp;SIGABRT&nbsp;C++&nbsp;signal<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Terminate&nbsp;program</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"handled.\n";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signal(SIGABRT,&nbsp;sigabrt_handler);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Cause&nbsp;abort</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;abort();&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;}&nbsp;</div></div><div></div><div>&nbsp;</div><div>Note:</div><div>虽然MSDN中没有详细地说明，但是你应该为你程序中的每个线程都安装SIGFPE, SIGILL和SIGSEGV signal hanlders。SIGABRT, SIGINT和SIGTERM signal hanlders对程序中的每个线程都起作用，因此你只需要在你的main函数中安装他们一次就够了。</div><div>获取异常信息 Retrieving Exception Information</div><div></div><div>译者注：这一小节不太懂，以后有时间再翻译</div><div>When an exception occurs you typically want to get the CPU state to determine the place in your code that caused the problem. You use the information to debug the problem. The way you retrieve the exception information differs depending on the exception handler you use.</div><div>In the SEH exception handler set with the SetUnhandledExceptionFilter() function, the exception information is retrieved from EXCEPTION_POINTERS structure passed as function parameter.</div><div>&nbsp;</div><div>In __try{}__catch(Expression){} construction you retrieve exception information using GetExceptionInformation() intrinsic function and pass it to the SEH exception filter function as parameter.</div><div>&nbsp;</div><div>In the SIGFPE and SIGSEGV signal handlers you can retrieve the exception information from the _pxcptinfoptrs global CRT variable that is declared in &lt;signal.h&gt;. This variable is not documented well in MSDN.</div><div>&nbsp;</div><div>In other signal handlers and in CRT error handlers you have no ability to easily extract the exception information. I found a workaround used in CRT code (see CRT 8.0 source files, invarg.c, line 104).</div><div>&nbsp;</div><div>The following code shows how to get current CPU state used as exception information.</div><div></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&nbsp; &nbsp;<span style="color: #0000FF; ">#if</span>&nbsp;_MSC_VER&gt;=1300<br />&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;rtcapi.h&gt;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#endif</span><br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;#ifndef&nbsp;_AddressOfReturnAddress<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Taken&nbsp;from:&nbsp;</span><span style="color: #008000; text-decoration: underline; ">http://msdn.microsoft.com/en-us/library/s975zw7k</span><span style="color: #008000; ">(VS.71).aspx</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;#ifdef&nbsp;__cplusplus<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#define</span>&nbsp;EXTERNC&nbsp;extern&nbsp;"C"<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#else</span><br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#define</span>&nbsp;EXTERNC<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#endif</span><br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;_ReturnAddress&nbsp;and&nbsp;_AddressOfReturnAddress&nbsp;should&nbsp;be&nbsp;prototyped&nbsp;before&nbsp;use&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;EXTERNC&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;*&nbsp;_AddressOfReturnAddress(<span style="color: #0000FF; ">void</span>);<br />&nbsp;&nbsp;&nbsp;EXTERNC&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;*&nbsp;_ReturnAddress(<span style="color: #0000FF; ">void</span>);<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#endif</span>&nbsp;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;The&nbsp;following&nbsp;function&nbsp;retrieves&nbsp;exception&nbsp;info</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;GetExceptionPointers(DWORD&nbsp;dwExceptionCode,&nbsp;<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;EXCEPTION_POINTERS**&nbsp;ppExceptionPointers)<br />&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;The&nbsp;following&nbsp;code&nbsp;was&nbsp;taken&nbsp;from&nbsp;VC++&nbsp;8.0&nbsp;CRT&nbsp;(invarg.c:&nbsp;line&nbsp;104)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EXCEPTION_RECORD&nbsp;ExceptionRecord;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CONTEXT&nbsp;ContextRecord;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(&amp;ContextRecord,&nbsp;0,&nbsp;<span style="color: #0000FF; ">sizeof</span>(CONTEXT));<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;#ifdef&nbsp;_X86_<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;dword&nbsp;ptr&nbsp;[ContextRecord.Eax],&nbsp;eax<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;dword&nbsp;ptr&nbsp;[ContextRecord.Ecx],&nbsp;ecx<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;dword&nbsp;ptr&nbsp;[ContextRecord.Edx],&nbsp;edx<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;dword&nbsp;ptr&nbsp;[ContextRecord.Ebx],&nbsp;ebx<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;dword&nbsp;ptr&nbsp;[ContextRecord.Esi],&nbsp;esi<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;dword&nbsp;ptr&nbsp;[ContextRecord.Edi],&nbsp;edi<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;word&nbsp;ptr&nbsp;[ContextRecord.SegSs],&nbsp;ss<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;word&nbsp;ptr&nbsp;[ContextRecord.SegCs],&nbsp;cs<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;word&nbsp;ptr&nbsp;[ContextRecord.SegDs],&nbsp;ds<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;word&nbsp;ptr&nbsp;[ContextRecord.SegEs],&nbsp;es<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;word&nbsp;ptr&nbsp;[ContextRecord.SegFs],&nbsp;fs<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;word&nbsp;ptr&nbsp;[ContextRecord.SegGs],&nbsp;gs<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushfd<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop&nbsp;[ContextRecord.EFlags]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ContextRecord.ContextFlags&nbsp;=&nbsp;CONTEXT_CONTROL;<br />&nbsp;&nbsp;&nbsp;#pragma&nbsp;warning(push)<br />&nbsp;&nbsp;&nbsp;#pragma&nbsp;warning(disable:4311)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ContextRecord.Eip&nbsp;=&nbsp;(ULONG)_ReturnAddress();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ContextRecord.Esp&nbsp;=&nbsp;(ULONG)_AddressOfReturnAddress();<br />&nbsp;&nbsp;&nbsp;#pragma&nbsp;warning(pop)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ContextRecord.Ebp&nbsp;=&nbsp;*((ULONG&nbsp;*)_AddressOfReturnAddress()-1);<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#elif</span>&nbsp;defined&nbsp;(_IA64_)&nbsp;||&nbsp;defined&nbsp;(_AMD64_)<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Need&nbsp;to&nbsp;fill&nbsp;up&nbsp;the&nbsp;Context&nbsp;in&nbsp;IA64&nbsp;and&nbsp;AMD64.&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RtlCaptureContext(&amp;ContextRecord);<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#else</span>&nbsp;&nbsp;/*&nbsp;defined&nbsp;(_IA64_)&nbsp;||&nbsp;defined&nbsp;(_AMD64_)&nbsp;*/<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ZeroMemory(&amp;ContextRecord,&nbsp;<span style="color: #0000FF; ">sizeof</span>(ContextRecord));<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#endif</span>&nbsp;&nbsp;/*&nbsp;defined&nbsp;(_IA64_)&nbsp;||&nbsp;defined&nbsp;(_AMD64_)&nbsp;*/<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ZeroMemory(&amp;ExceptionRecord,&nbsp;<span style="color: #0000FF; ">sizeof</span>(EXCEPTION_RECORD));<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExceptionRecord.ExceptionCode&nbsp;=&nbsp;dwExceptionCode;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExceptionRecord.ExceptionAddress&nbsp;=&nbsp;_ReturnAddress();<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EXCEPTION_RECORD*&nbsp;pExceptionRecord&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;EXCEPTION_RECORD;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pExceptionRecord,&nbsp;&amp;ExceptionRecord,&nbsp;<span style="color: #0000FF; ">sizeof</span>(EXCEPTION_RECORD));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CONTEXT*&nbsp;pContextRecord&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;CONTEXT;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pContextRecord,&nbsp;&amp;ContextRecord,&nbsp;<span style="color: #0000FF; ">sizeof</span>(CONTEXT));<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*ppExceptionPointers&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;EXCEPTION_POINTERS;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*ppExceptionPointers)-&gt;ExceptionRecord&nbsp;=&nbsp;pExceptionRecord;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*ppExceptionPointers)-&gt;ContextRecord&nbsp;=&nbsp;pContextRecord;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;}</div></div><div></div><div>Visual C++ Complier Flags</div><div></div><div>Visual C++编译器中有一些编译选项和异常处理有关。</div><div>在Project Properties-&gt;Configuration Properties-&gt;C/C++ -&gt;Code Generation中可以找到这些选项。</div><div>异常处理模型Exception Handling Model</div><div>你可以为VC++编译器选择异常处理模型。选项/EHs(或者EHsc)用来指定同步异常处理模型，/EHa用来指定异步异常处理模型。可以查看下面参考小节的"/EH(Exception Handling Model)"以获取更多的信息。</div><div>Floating Point Exceptions</div><div>你可以使用/fp:except编译选项打开float point exceptions。</div><div>缓冲区安全检查Buffer Security Checks</div><div>你可以使用/GS(Buffer Security Check)选项来强制编译器插入代码以检查缓冲区溢出。缓冲区溢出指的是一大块数据被写入一块较小的缓冲区中。当检测到缓冲区溢出，CRT calls internal security handler that invokes Watson directly。</div><div>Note:</div><div>在VC++(CRT7.1)中，缓冲区溢出被检测到时，CRT会调用由_set_security_error_handler函数设置的处理器。然而，在之后的VC版本中这个函数被废弃。</div><div>从CRT8.0开始，你在你的代码中不能截获安全错误。当缓冲区溢出被检测到时，CRT会直接请求Watson，而不是调用unhandled exception filter。这样做是由于安全原因并且微软不打算改变这种行为。</div><div>更多的信息请参考如下链接</div><div>https://connect.microsoft.com/VisualStudio/feedback/details/101337/a-proposal-to-make-dr-watson-invocation-configurable</div><div>http://blog.kalmbachnet.de/?postid=75</div><div>异常处理和CRT链接Exception Handling and CRT Linkage</div><div></div><div>你的应用程序中的每个module（EXE, DLL）都需要链接CRT。你可以将CRT链接为多线程静态库(multi-threaded static library)或者多线程动态链接库(multi-threaded dynamic link library)。如果你设置了CRT error handlers，例如你设置了terminate handler, unexcepted handler, pure call handler, invalid parameter handler, new operator error handler or a signal handler，那么他们将只在你链接的CRT上运行，并且不会捕获其他CRT模块中的异常（如果存在的话），因为每个CRT模块都有它自己的内部状态。</div><div>多个工程中的module可以共享CRT DLL。这将使得被链接的CRT代码达到最小化，并且CRT DLL中的所有异常都会被立刻处理。这也是推荐使用multi-threaded CRT DLL作为CRT链接方式的原因。</div><img src ="http://www.cppblog.com/API/aggbug/208965.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/API/" target="_blank">C++技术中心</a> 2014-11-26 15:12 <a href="http://www.cppblog.com/API/archive/2014/11/26/208965.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>panel和wxBoxSizer</title><link>http://www.cppblog.com/API/archive/2014/09/28/208442.html</link><dc:creator>C++技术中心</dc:creator><author>C++技术中心</author><pubDate>Sun, 28 Sep 2014 08:13:00 GMT</pubDate><guid>http://www.cppblog.com/API/archive/2014/09/28/208442.html</guid><wfw:comment>http://www.cppblog.com/API/comments/208442.html</wfw:comment><comments>http://www.cppblog.com/API/archive/2014/09/28/208442.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/API/comments/commentRss/208442.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/API/services/trackbacks/208442.html</trackback:ping><description><![CDATA[<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">//</span><span style="color: #008000; ">1.加入boxSizer19</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;wxBoxSizer*&nbsp;topSizer&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;wxBoxSizer(wxVERTICAL);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>-&gt;SetSizer(topSizer);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;wxPanel*&nbsp;upPanel&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;wxPanel(&nbsp;<span style="color: #0000FF; ">this</span>,&nbsp;ID_BOT_PANEL2&nbsp;,wxDefaultPosition,&nbsp;wxSize(800,&nbsp;100));<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;upPanel-&gt;SetBackgroundColour(*wxBLACK);<span style="color: #008000; ">//</span><span style="color: #008000; ">黑色背景</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;wxPanel*&nbsp;centerPanel&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;wxPanel(&nbsp;<span style="color: #0000FF; ">this</span>,&nbsp;ID_BOT_PANEL3,wxDefaultPosition,&nbsp;wxSize(800,&nbsp;100)&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;centerPanel-&gt;SetBackgroundColour(*wxWHITE);<span style="color: #008000; ">//</span><span style="color: #008000; ">白色背景</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;wxPanel*&nbsp;bottomPanel&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;wxPanel(&nbsp;<span style="color: #0000FF; ">this</span>,&nbsp;ID_BOT_PANEL4,&nbsp;wxDefaultPosition,&nbsp;wxSize(800,&nbsp;100));<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bottomPanel-&gt;SetBackgroundColour(*wxRED);<span style="color: #008000; ">//</span><span style="color: #008000; ">红色背景</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;topSizer-&gt;Add(upPanel,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">垂直方向可拉伸</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wxEXPAND|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">水平方向自动填充</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wxALL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">四周都有边框</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">边框宽度为10</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;topSizer-&gt;Add(centerPanel,0,wxEXPAND);<br />&nbsp;&nbsp;&nbsp;&nbsp;topSizer-&gt;Add(bottomPanel,0,wxEXPAND);</div><img src ="http://www.cppblog.com/API/aggbug/208442.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/API/" target="_blank">C++技术中心</a> 2014-09-28 16:13 <a href="http://www.cppblog.com/API/archive/2014/09/28/208442.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于warning C4819</title><link>http://www.cppblog.com/API/archive/2012/11/12/195056.html</link><dc:creator>C++技术中心</dc:creator><author>C++技术中心</author><pubDate>Mon, 12 Nov 2012 02:00:00 GMT</pubDate><guid>http://www.cppblog.com/API/archive/2012/11/12/195056.html</guid><wfw:comment>http://www.cppblog.com/API/comments/195056.html</wfw:comment><comments>http://www.cppblog.com/API/archive/2012/11/12/195056.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/API/comments/commentRss/195056.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/API/services/trackbacks/195056.html</trackback:ping><description><![CDATA[<p>编译VC++程序的时候出现如下提示警告：</p>
<p>warning C4819: The file contains a character that cannot be represented in the current code page (936). Save the file in Unicode format to prevent data loss</p>
<p>因为只是一个warning，不影响正常编译，所以并没有引起大家多大的关注。我一开始的时候也是如此。但是后来出现的次数多了，发现这个警告和在程序Debug的时候<br />无法停在断点，刷刷刷就过去了根本无法进行Debug。而罪魁祸首就是这个warning，改正了这个warning就能进行Debug了。</p>
<p>下面讲述我是怎么消除这个警告的。</p>
<p>这个警告的意思是：在该文件中有一个或多个字符不是Unicode字符！要求把这个字符变成Unicode字符。</p>
<p>难题：在编译信息里并没有提示是哪个字符，或者是在哪一行里出现的该字符。查找起来非常的难，甚至是不可能的任务！</p>
<p>我在网络上找了好多资料都没有找到解决方法。因为大家都不注意这个不影响编译的警告。后来在一个国外的网站上找到了解决的方法。很简单，这个方法根本不需要知道具体是哪个字符在捣鬼！</p>
<p>解决方法：打开出现warning的文件，Ctrl+A全选，然后在文件菜单：file-&gt;advanced save options ，在弹出的选项中选择新的编码方式为：UNICODE codepage 1200 ，点击确定，问题就解决了。</p><img src ="http://www.cppblog.com/API/aggbug/195056.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/API/" target="_blank">C++技术中心</a> 2012-11-12 10:00 <a href="http://www.cppblog.com/API/archive/2012/11/12/195056.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Memcache存储大数据的问题</title><link>http://www.cppblog.com/API/archive/2012/10/19/193536.html</link><dc:creator>C++技术中心</dc:creator><author>C++技术中心</author><pubDate>Fri, 19 Oct 2012 09:20:00 GMT</pubDate><guid>http://www.cppblog.com/API/archive/2012/10/19/193536.html</guid><wfw:comment>http://www.cppblog.com/API/comments/193536.html</wfw:comment><comments>http://www.cppblog.com/API/archive/2012/10/19/193536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/API/comments/commentRss/193536.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/API/services/trackbacks/193536.html</trackback:ping><description><![CDATA[<p><span style="font-family: 宋体; color: #444444; font-size: 10.5pt"><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span class="link_title"></span></span></span></span><span style="font-family: 宋体; color: #444444; font-size: 10.5pt"><span style="font-family: arial black, avant garde"><span style="color: #0000ff">Memcached存储单个item最大数据是在1MB内，如果数据超过1M,存取set和get是都是返回false，而且引起性能的问题。</span></span></span></p>
<p><span style="font-family: 宋体; color: #444444; font-size: 10.5pt"><span style="font-family: arial black, avant garde"><span style="color: #0000ff">我们之前对排行榜的数据进行缓存，由于排行榜在我们所有sql select查询里面占了30%，而且我们排行榜每小时更新一次，所以必须对数据做缓存。为了清除缓存方便，把所有的用户的数据放在同一key中，由于memcached:set的时候没有压缩数据。在测试服测试的时候，没发现问题，当上线的时候，结果发现，在线人数刚刚490人的时候，服务器load average飘到7.9。然后我们去掉缓存，一下子就下降到0.59。</span></span></span></p>
<p><span style="font-family: 宋体; color: #444444; font-size: 10.5pt"></span></p>
<p><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span style="font-family: 宋体; font-size: 10.5pt">所以Memcahce不适合缓存大数据，超过</span><span style="font-family: 宋体; font-size: 10.5pt">1MB的数据</span><span style="font-family: 'Times New Roman'; font-size: 10.5pt">，可以考虑在客户端压缩或拆分到多个</span><span style="font-family: 宋体; font-size: 10.5pt">key</span><span style="font-family: 'Times New Roman'; font-size: 10.5pt">中。大的数据在进行load和uppack到内存的时候需要花很长时间，从而降低服务器的性能。</span></span></span></p>
<p><span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span style="font-family: 宋体; font-size: 10.5pt">Memcached</span><span style="font-family: 宋体; font-size: 10.5pt">支持最大的存储对象为</span><span style="font-family: 宋体; font-size: 10.5pt">1M</span><span style="font-family: 宋体; font-size: 10.5pt">。这个值由其内存分配机制决定的。</span></span></span></span></span></p>
<p><span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span style="font-family: 宋体; font-size: 10.5pt">memcached</span><span style="font-family: 'Times New Roman'; font-size: 10.5pt">默认情况下采用了名为</span><span style="font-family: 宋体; font-size: 10.5pt">Slab Allocator</span><span style="font-family: 'Times New Roman'; font-size: 10.5pt">的机制分配、管理内存。在该机制出现以前，内存的分配是通过对所有记录简单地进行</span><span style="font-family: 宋体; font-size: 10.5pt">malloc</span><span style="font-family: 'Times New Roman'; font-size: 10.5pt">和</span><span style="font-family: 宋体; font-size: 10.5pt">free</span><span style="font-family: 'Times New Roman'; font-size: 10.5pt">来进行的。但是，这种方式会导致内存碎片，加重操作系统内存管理器的负担，最坏的情况下，会导致操作系统比</span><span style="font-family: 宋体; font-size: 10.5pt">memcached</span><span style="font-family: 'Times New Roman'; font-size: 10.5pt">进程本身还慢。</span><span style="font-family: 宋体; font-size: 10.5pt">Slab Allocator</span><span style="font-family: 'Times New Roman'; font-size: 10.5pt">就是为解决该问题而诞生的。<span style="font-family: 宋体; font-size: 10.5pt">Slab Allocator</span><span style="font-family: 'Times New Roman'; font-size: 10.5pt">的基本原理是按照预先规定的大小，将分配的内存分割成特定长度的块，以完全解决内存碎片问题.</span></span></span></span></span></span></span></p>
<p><span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-family: 'Times New Roman'; font-size: 10.5pt">今天（2012-03-16）我们重新测试了memcached ::set的数据大小。可能是我们用php的memcached扩展是最新版，set数据的时候是默认压缩的。set 数据：</span></span></span></span></span></span></span></p>
<p><span style="font-family: 'Times New Roman'; color: #0000ff"></span></p>
<div class="dp-highlighter bg_plain">
<div class="bar">
<div class="tools"><strong>[plain]</strong> <a class="ViewSource" title="view plain" href="http://blog.csdn.net/hguisu/article/details/6163621#"><u><font color="#000080">view plain</font></u></a><a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/hguisu/article/details/6163621#"><u><font color="#000080">copy</font></u></a><a class="PrintSource" title="print" href="http://blog.csdn.net/hguisu/article/details/6163621#"><u><font color="#000080">print</font></u></a><a class="About" title="?" href="http://blog.csdn.net/hguisu/article/details/6163621#"><u><font color="#000080">?</font></u></a></div></div>
<ol><li class="alt"><span>$ac = new memcahed(); </span></li><li><span>$data = str_repeat('a', 1024* 1024); //1M的数据 </span></li><li class="alt"><span>$r = $ac-&gt;set('key', $data, 9999); </span></li><li><span>//或者 </span></li><li class="alt"><span>$data = str_repeat('a', 1024* 1024*100);//100M的数据 </span></li><li><span>$r = $ac-&gt;set('key', $data, 9999); </span></li></ol></div><pre style="display: none" class="plain" name="code">$ac = new memcahed();
$data = str_repeat('a', 1024* 1024); //1M的数据
$r  =  $ac-&gt;set('key', $data, 9999);
//或者
$data = str_repeat('a', 1024* 1024*100);//100M的数据
$r  =  $ac-&gt;set('key', $data, 9999);</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: arial black, avant garde"><span style="background-color: #ffffff"><span style="color: #3333ff">不论是1M的数据还是100M的数据，都能set成功。后来我发现，memcached</span></span><span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-family: 'Times New Roman'; font-size: 10.5pt">set数据的时候是默认压缩的。由于这个这个是重复的字符串，压缩率高达1000倍。因此100M的数据压缩后实际也就100k而已。</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: arial black, avant garde"><span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-family: 'Times New Roman'; font-size: 10.5pt">当我设置：</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="font-family: 'Times New Roman'; color: #0000ff"></span></p>
<div class="dp-highlighter bg_plain">
<div class="bar">
<div class="tools"><strong>[plain]</strong> <a class="ViewSource" title="view plain" href="http://blog.csdn.net/hguisu/article/details/6163621#"><u><font color="#000080">view plain</font></u></a><a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/hguisu/article/details/6163621#"><u><font color="#000080">copy</font></u></a><a class="PrintSource" title="print" href="http://blog.csdn.net/hguisu/article/details/6163621#"><u><font color="#000080">print</font></u></a><a class="About" title="?" href="http://blog.csdn.net/hguisu/article/details/6163621#"><u><font color="#000080">?</font></u></a></div></div>
<ol><li class="alt"><span>$ac-&gt;setOption(memcahed::OPT_COMPRESSION,0); //不压缩存储数据。 </span></li><li><span>$data = str_repeat('a', 1024* 1024); //1M数据 </span></li><li class="alt"><span>$r = $ac-&gt;set('key', $data, 9999);//1M的数据set不成功。 </span></li></ol></div><pre style="display: none" class="plain" name="code">$ac-&gt;setOption(memcahed::OPT_COMPRESSION,0); //不压缩存储数据。
$data = str_repeat('a', 1024* 1024); //1M数据
$r  =  $ac-&gt;set('key', $data, 9999);//1M的数据set不成功。</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-family: 'Times New Roman'; font-size: 10.5pt">也就是说memcached server不能存储超过1M的数据，但是<span style="font-family: Verdana; color: white; font-size: 10.5pt" lang="EN-US"><span style="color: #000000"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: arial black, avant garde"><span style="color: #0000ff"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-family: 'Times New Roman'; font-size: 10.5pt">经过</span></span></span></span></span></span></span>客户端压缩数据后，只要小于1M的数据都能存储成功。</span></span></span></span></span></span></span></p>
<p><span style="font-family: Verdana; font-size: 10.5pt" lang="EN-US"><span style="font-size: 10.5pt" lang="AR-SA"><span style="font-family: 'arial black', 'avant garde'"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-family: 'Times New Roman'; font-size: 10.5pt"><span style="font-weight: bold">memcached相关知识：</span><br /></span></span></span></span></span></p>
<p>&nbsp;</p>
<p><strong>1、memcached的基本设置 <br />1）启动Memcache的服务器端 </strong><br /># /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid</p>
<p>-d选项是启动一个守护进程， <br />-m是分配给Memcache使用的内存数量，单位是MB，我这里是10MB， <br />-u是运行Memcache的用户，我这里是root， <br />-l是监听的服务器IP地址，如果有多个地址的话，我这里指定了服务器的IP地址192.168.0.200， <br />-p是设置Memcache监听的端口，我这里设置了12000，最好是1024以上的端口， <br />-c选项是最大运行的并发连接数，默认是1024，我这里设置了256，按照你服务器的负载量来设定， <br />-P是设置保存Memcache的pid文件，我这里是保存在 /tmp/memcached.pid，</p>
<p>2）如果要结束Memcache进程，执行：</p>
<p># kill `cat /tmp/memcached.pid`</p>
<p><a href="http://baike.baidu.com/view/273836.htm"><span style="color: #000000">哈希算法</span></a><span style="color: #000000">将</span>任意长度的二进制值映射为固定长度的较小二进制值，这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该</p>
<p>段落的一个字母，随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入，在计算上是不可能的。</p>
<p>&nbsp;</p>
<p><strong>2、适用memcached的业务场景？</strong></p>
<p>1）如果网站包含了访问量很大的动态网页，因而数据库的负载将会很高。由于大部分数据库请求都是读操作，那么memcached可以显著地减小数据库负载。</p>
<p>2）如果数据库服务器的负载比较低但CPU使用率很高，这时可以缓存计算好的结果（ computed objects ）和渲染后的网页模板（enderred templates）。</p>
<p>3）利用memcached可以缓存<strong>session数据</strong>、临时数据以减少对他们的数据库写操作。</p>
<p>4）缓存一些很小但是被频繁访问的文件。</p>
<p>5）缓存Web 'services'（非IBM宣扬的Web Services，译者注）或RSS feeds的结果.。</p>
<p><strong>3、不适用memcached的业务场景？</strong></p>
<p>&nbsp;</p>
<p>1）缓存对象的大小大于1MB </p>
<p>Memcached本身就不是为了处理庞大的多媒体（large media）和巨大的二进制块（streaming huge blobs）而设计的。 </p>
<p>2）key的长度大于250字符 </p>
<p>3）虚拟主机不让运行memcached服务 </p>
<p>如果应用本身托管在低端的虚拟私有服务器上，像vmware, xen这类虚拟化技术并不适合运行memcached。Memcached需要接管和控制大块的内存，如果memcached管理 的内存被OS或 hypervisor交换出去，memcached的性能将大打折扣。</p>
<p>4）应用运行在不安全的环境中 </p>
<p>Memcached为提供任何安全策略，仅仅通过telnet就可以访问到memcached。如果应用运行在共享的系统上，需要着重考虑安全问题。</p>
<p>5）业务本身需要的是持久化数据或者说需要的应该是database</p>
<p>&nbsp;</p>
<p><strong>4、 不能能够遍历memcached中所有的item</strong></p>
<p>这个操作的速度相对缓慢且阻塞其他的操作（这里的缓慢时相比memcached其他的命令）。memcached所有非调试（non-debug）命令，例如add, set, get, fulsh等无论</p>
<p>memcached中存储了多少数据，它们的执行都只消耗常量时间。任何遍历所有item的命令执行所消耗的时间，将随着memcached中数据量的增加而增加。当其他命令因为等待（遍历所有item的命令执行完毕）而不能得到执行，因而阻塞将发生。</p><strong>5、 memcached能接受的key的最大长度是250个字符</strong> 
<p>memcached能接受的key的最大长度是250个字符。需要注意的是，250是memcached服务器端内部的限制。如果使用的Memcached客户端支持"key的前缀"或类似特性，那么key（前缀+原始key）的最大长度是可以超过250个字符的。推荐使用较短的key，这样可以节省内存和带宽。</p><strong>6、 单个item的大小被限制在1M byte之内</strong> 
<p>因为内存分配器的算法就是这样的。</p>
<p>详细的回答：</p>
<p>1）Memcached的内存存储引擎，使用slabs来管理内存。内存被分成大小不等的slabs chunks（先分成大小相等的slabs，然后每个slab被分成大小相等chunks，不同slab的chunk大小是不相等的）。chunk的大小依次从一个最小数开始，按某个因子增长，直到达到最大的可能值。如果最小值为400B，最大值是1MB，因子是1.20，各个slab的chunk的大小依次是：</p>
<p>slab1 - 400B；slab2 - 480B；slab3 - 576B ...slab中chunk越大，它和前面的slab之间的间隙就越大。因此，最大值越大，内存利用率越低。Memcached必须为每个slab预先分配内存，因此如果设置了较小的因子和较大的最大值，会需要为Memcached提供更多的内存。</p>
<p>2）不要尝试向memcached中存取很大的数据，例如把巨大的网页放到mencached中。因为将大数据load和unpack到内存中需要花费很长的时间，从而导致系统的性能反而不好。如果确实需要存储大于1MB的数据，可以修改slabs.c：POWER_BLOCK的值，然后重新编译memcached；或者使用低效的malloc/free。另外，可以使用数据库、MogileFS等方案代替Memcached系统。</p><strong>7、 memcached的内存分配器是如何工作的？为什么不适用malloc/free！？为何要使用slabs？</strong> 
<p>实际上，这是一个编译时选项。默认会使用内部的slab分配器，而且确实应该使用内建的slab分配器。最早的时候，memcached只使用malloc/free来管理内存。然而，这种方式不能与OS的内存管理以前很好地工作。反复地malloc/free造成了内存碎片，OS最终花费大量的时间去查找连续的内存块来满足malloc的请求，而不是运行memcached进程。slab分配器就是为了解决这个问题而生的。内存被分配并划分成chunks，一直被重复使用。因为内存被划分成大小不等的slabs，如果item的大小与被选择存放它的slab不是很合适的话，就会浪费一些内存。</p>
<p><strong>8、memcached对item的过期时间有什么限制？</strong></p>
<p>item对象的过期时间最长可以达到30天。memcached把传入的过期时间（时间段）解释成时间点后，一旦到了这个时间点，memcached就把item置为失效状态，这是一个简单但obscure的机制。</p>
<p><strong>9、什么是二进制协议，是否需要关注？</strong></p>
<p>二进制协议尝试为端提供一个更有效的、可靠的协议，减少客户端/服务器端因处理协议而产生的CPU时间。根据Facebook的测试，解析ASCII协议是memcached中消耗CPU时间最多的</p>
<p>环节。</p>
<p><strong>10、 memcached的内存分配器是如何工作的？为什么不适用malloc/free！？为何要使用slabs？</strong></p>
<p>实际上，这是一个编译时选项。默认会使用内部的slab分配器，而且确实应该使用内建的slab分配器。最早的时候，memcached只使用malloc/free来管理内存。然而，这种方式不能与OS的内存管理以前很好地工作。反复地malloc/free造成了内存碎片，OS最终花费大量的时间去查找连续的内存块来满足malloc的请求，而不是运行memcached进程。slab分配器就是为了解决这个问题而生的。内存被分配并划分成chunks，一直被重复使用。因为内存被划分成大小不等的slabs，如果item的大小与被选择存放它的slab不是很合适的话，就会浪费一些内存。</p>
<p><strong>11、memcached是原子的吗？</strong></p>
<p>所有的被发送到memcached的单个命令是完全原子的。如果您针对同一份数据同时发送了一个set命令和一个get命令，它们不会影响对方。它们将被串行化、先后执行。即使在多线程模式，所有的命令都是原子的。然是，命令序列不是原子的。如果首先通过get命令获取了一个item，修改了它，然后再把它set回memcached，系统不保证这个item没有被其他进程（process，未必是操作系统中的进程）操作过。memcached 1.2.5以及更高版本，提供了gets和cas命令，它们可以解决上面的问题。如果使用gets命令查询某个key的item，memcached会返回该item当前值的唯一标识。如果客户端程序覆写了这个item并想把它写回到memcached中，可以通过cas命令把那个唯一标识一起发送给memcached。如果该item存放在memcached中的唯一标识与您提供的一致，写操作将会成功。如果另一个进程在这期间也修改了这个item，那么该item存放在memcached中的唯一标识将会改变，写操作就会</p>
<p>失败。<br /><br />
<div><strong style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: #f5f5f5; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; padding-top: 0px">Windows下的Memcache安装</strong><span style="text-align: left; line-height: 19px; background-color: #f5f5f5; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px">：</span><br style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: #f5f5f5; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; padding-top: 0px" /><span style="text-align: left; line-height: 19px; background-color: #f5f5f5; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px">1. 下载</span><a style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: #f5f5f5; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #0069d6; font-size: 13px; padding-top: 0px" href="http://jehiah.cz/projects/memcached-win32" target="_blank"><span style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; color: #1359ae; padding-top: 0px">memcache</span></a><span style="text-align: left; line-height: 19px; background-color: #f5f5f5; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px">的windows稳定版，解压放某个盘下面，比如在c:/memcached</span><br style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: #f5f5f5; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; padding-top: 0px" /><span style="text-align: left; line-height: 19px; background-color: #f5f5f5; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px">2. 在终端（也即cmd命令界面）下输入 &#8216;c:/memcached/memcached.exe -d install&#8217; 安装</span><br style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: #f5f5f5; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; padding-top: 0px" /><span style="text-align: left; line-height: 19px; background-color: #f5f5f5; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px">3. 再输入： &#8216;c:/memcached/memcached.exe -d start&#8217; 启动。NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。</span>&nbsp;</div>
<p><br /><br />/usr/local/memcached/bin/memcached -u root -d -m 3072 -l 192.168.121.130 -p 50008 -U 0 -P /var/run/memcache.pid<br /><br /></p><img src ="http://www.cppblog.com/API/aggbug/193536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/API/" target="_blank">C++技术中心</a> 2012-10-19 17:20 <a href="http://www.cppblog.com/API/archive/2012/10/19/193536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>memcached的删除机制和发展方向</title><link>http://www.cppblog.com/API/archive/2012/10/08/192976.html</link><dc:creator>C++技术中心</dc:creator><author>C++技术中心</author><pubDate>Mon, 08 Oct 2012 01:39:00 GMT</pubDate><guid>http://www.cppblog.com/API/archive/2012/10/08/192976.html</guid><wfw:comment>http://www.cppblog.com/API/comments/192976.html</wfw:comment><comments>http://www.cppblog.com/API/archive/2012/10/08/192976.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/API/comments/commentRss/192976.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/API/services/trackbacks/192976.html</trackback:ping><description><![CDATA[<div class="content">
<h1 class="entry-title"><a title="Permalink to memcached全面剖析&#8211;3.memcached的删除机制和发展方向" href="http://tech.idv2.com/2008/07/16/memcached-003/" rel="bookmark">memcached全面剖析&#8211;3.memcached的删除机制和发展方向</a></h1>
<div class="entry-content">
<p>下面是《memcached全面剖析》的第三部分。</p>
<ul><li>发表日：2008/7/16</li><li>作者：前坂徹(Toru Maesaka)</li><li>原文链接：<a href="http://gihyo.jp/dev/feature/01/memcached/0003">http://gihyo.jp/dev/feature/01/memcached/0003</a></li></ul>
<p>前几次的文章在这里：</p>
<ul><li>第1次：<a href="http://tech.idv2.com/2008/07/10/memcached-001/">http://tech.idv2.com/2008/07/10/memcached-001/</a></li><li>第2次：<a href="http://tech.idv2.com/2008/07/11/memcached-002/">http://tech.idv2.com/2008/07/11/memcached-002/</a></li></ul>
<p><span id="more-600"></span></p>
<p>memcached是缓存，所以数据不会永久保存在服务器上，这是向系统中引入memcached的前提。 本次介绍memcached的数据删除机制，以及memcached的最新发展方向&#8212;&#8212;二进制协议（Binary Protocol） 和外部引擎支持。</p>
<h1>memcached在数据删除方面有效利用资源</h1>
<h2>数据不会真正从memcached中消失</h2>
<p><a href="http://tech.idv2.com/2008/07/11/memcached-002/">上次</a>介绍过，memcached不会释放已分配的内存。记录超时后，客户端就无法再看见该记录（invisible，透明）， 其存储空间即可重复使用。</p>
<h2>Lazy Expiration</h2>
<p>memcached内部不会监视记录是否过期，而是在get时查看记录的时间戳，检查记录是否过期。 这种技术被称为lazy（惰性）expiration。因此，memcached不会在过期监视上耗费CPU时间。</p>
<h1>LRU：从缓存中有效删除数据的原理</h1>
<p>memcached会优先使用已超时的记录的空间，但即使如此，也会发生追加新记录时空间不足的情况， 此时就要使用名为 Least Recently Used（LRU）机制来分配空间。 顾名思义，这是删除&#8220;最近最少使用&#8221;的记录的机制。 因此，当memcached的内存空间不足时（无法从<a href="http://tech.idv2.com/2008/07/11/memcached-002/">slab class</a>获取到新的空间时），就从最近未被使用的记录中搜索，并将其空间分配给新的记录。 从缓存的实用角度来看，该模型十分理想。</p>
<p>不过，有些情况下LRU机制反倒会造成麻烦。memcached启动时通过&#8220;-M&#8221;参数可以禁止LRU，如下所示：</p><pre><code>$ memcached -M -m 1024
</code></pre>
<p>启动时必须注意的是，小写的&#8220;-m&#8221;选项是用来指定最大内存大小的。不指定具体数值则使用默认值64MB。</p>
<p>指定&#8220;-M&#8221;参数启动后，内存用尽时memcached会返回错误。 话说回来，memcached毕竟不是存储器，而是缓存，所以推荐使用LRU。</p>
<h1>memcached的最新发展方向</h1>
<p>memcached的roadmap上有两个大的目标。一个是二进制协议的策划和实现，另一个是外部引擎的加载功能。</p>
<h2>关于二进制协议</h2>
<p>使用二进制协议的理由是它不需要文本协议的解析处理，使得原本高速的memcached的性能更上一层楼， 还能减少文本协议的漏洞。目前已大部分实现，开发用的代码库中已包含了该功能。memcached的下载页面上有代码库的链接。</p>
<ul><li><a href="http://danga.com/memcached/download.bml">http://danga.com/memcached/download.bml</a></li></ul>
<h2>二进制协议的格式</h2>
<p>协议的包为24字节的帧，其后面是键和无结构数据（Unstructured Data）。 实际的格式如下（引自协议文档）：</p><pre><code> Byte/     0       |       1       |       2       |       3       |   
    /              |               |               |               |   
   |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
   +---------------+---------------+---------------+---------------+
  0/ HEADER                                                        /   
   /                                                               /   
   /                                                               /   
   /                                                               /   
   +---------------+---------------+---------------+---------------+
 24/ COMMAND-SPECIFIC EXTRAS (as needed)                           /   
  +/  (note length in th extras length header field)               /   
   +---------------+---------------+---------------+---------------+
  m/ Key (as needed)                                               /   
  +/  (note length in key length header field)                     /   
   +---------------+---------------+---------------+---------------+
  n/ Value (as needed)                                             /   
  +/  (note length is total body length header field, minus        /   
  +/   sum of the extras and key length body fields)               /   
   +---------------+---------------+---------------+---------------+
  Total 24 bytes
</code></pre>
<p>如上所示，包格式十分简单。需要注意的是，占据了16字节的头部(HEADER)分为 请求头（Request Header）和响应头（Response Header）两种。 头部中包含了表示包的有效性的Magic字节、命令种类、键长度、值长度等信息，格式如下：</p><pre><code>Request Header

 Byte/     0       |       1       |       2       |       3       |
    /              |               |               |               |
   |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
   +---------------+---------------+---------------+---------------+
  0| Magic         | Opcode        | Key length                    |
   +---------------+---------------+---------------+---------------+
  4| Extras length | Data type     | Reserved                      |
   +---------------+---------------+---------------+---------------+
  8| Total body length                                             |
   +---------------+---------------+---------------+---------------+
 12| Opaque                                                        |
   +---------------+---------------+---------------+---------------+
 16| CAS                                                           |
   |                                                               |
   +---------------+---------------+---------------+---------------+

Response Header

 Byte/     0       |       1       |       2       |       3       |
    /              |               |               |               |
   |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
   +---------------+---------------+---------------+---------------+
  0| Magic         | Opcode        | Key Length                    |
   +---------------+---------------+---------------+---------------+
  4| Extras length | Data type     | Status                        |
   +---------------+---------------+---------------+---------------+
  8| Total body length                                             |
   +---------------+---------------+---------------+---------------+
 12| Opaque                                                        |
   +---------------+---------------+---------------+---------------+
 16| CAS                                                           |
   |                                                               |
   +---------------+---------------+---------------+---------------+
</code></pre>
<p>如希望了解各个部分的详细内容，可以checkout出memcached的二进制协议的代码树， 参考其中的docs文件夹中的protocol_binary.txt文档。</p>
<h2>HEADER中引人注目的地方</h2>
<p>看到HEADER格式后我的感想是，键的上限太大了！现在的memcached规格中，键长度最大为250字节， 但二进制协议中键的大小用2字节表示。因此，理论上最大可使用65536字节（2<sup>16</sup>）长的键。 尽管250字节以上的键并不会太常用，二进制协议发布之后就可以使用巨大的键了。</p>
<p>二进制协议从下一版本1.3系列开始支持。</p>
<h1>外部引擎支持</h1>
<p>我去年曾经试验性地将memcached的存储层改造成了可扩展的（pluggable）。</p>
<ul><li><a href="http://alpha.mixi.co.jp/blog/?p=129">http://alpha.mixi.co.jp/blog/?p=129</a></li></ul>
<p>MySQL的Brian Aker看到这个改造之后，就将代码发到了memcached的邮件列表。memcached的开发者也十分感兴趣，就放到了roadmap中。现在由我和memcached的开发者Trond Norbye协同开发（规格设计、实现和测试）。 和国外协同开发时时差是个大问题，但抱着相同的愿景， 最后终于可以将可扩展架构的原型公布了。 代码库可以从<a href="http://danga.com/memcached/download.bml">memcached的下载页面</a>上访问。</p>
<h2>外部引擎支持的必要性</h2>
<p>世界上有许多memcached的派生软件，其理由是希望永久保存数据、实现数据冗余等， 即使牺牲一些性能也在所不惜。我在开发memcached之前，在mixi的研发部也曾经 考虑过重新发明memcached。</p>
<p>外部引擎的加载机制能封装memcached的网络功能、事件处理等复杂的处理。 因此，现阶段通过强制手段或重新设计等方式使memcached和存储引擎合作的困难 就会烟消云散，尝试各种引擎就会变得轻而易举了。</p>
<h2>简单API设计的成功的关键</h2>
<p>该项目中我们最重视的是API设计。函数过多，会使引擎开发者感到麻烦； 过于复杂，实现引擎的门槛就会过高。因此，最初版本的接口函数只有13个。 具体内容限于篇幅，这里就省略了，仅说明一下引擎应当完成的操作：</p>
<ul><li>引擎信息（版本等）</li><li>引擎初始化</li><li>引擎关闭</li><li>引擎的统计信息</li><li>在容量方面，测试给定记录能否保存</li><li>为item（记录）结构分配内存</li><li>释放item（记录）的内存</li><li>删除记录</li><li>保存记录</li><li>回收记录</li><li>更新记录的时间戳</li><li>数学运算处理</li><li>数据的flush</li></ul>
<p>对详细规格有兴趣的读者，可以checkout engine项目的代码，阅读器中的engine.h。</p>
<h2>重新审视现在的体系</h2>
<p>memcached支持外部存储的难点是，网络和事件处理相关的代码（核心服务器）与 内存存储的代码紧密关联。这种现象也称为tightly coupled（紧密耦合）。 必须将内存存储的代码从核心服务器中独立出来，才能灵活地支持外部引擎。 因此，基于我们设计的API，memcached被重构成下面的样子：</p>
<p><img alt="memcached-0003-001.png" src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0003-001.png" /></p>
<p>重构之后，我们与1.2.5版、二进制协议支持版等进行了性能对比，证实了它不会造成性能影响。</p>
<p>在考虑如何支持外部引擎加载时，让memcached进行并行控制（concurrency control）的方案是最为容易的， 但是对于引擎而言，并行控制正是性能的真谛，因此我们采用了将多线程支持完全交给引擎的设计方案。</p>
<p>以后的改进，会使得memcached的应用范围更为广泛。</p>
<h1>总结</h1>
<p>本次介绍了memcached的超时原理、内部如何删除数据等，在此之上又介绍了二进制协议和 外部引擎支持等memcached的最新发展方向。这些功能要到1.3版才会支持，敬请期待！</p>
<p>这是我在本连载中的最后一篇。感谢大家阅读我的文章！</p>
<p>下次由长野来介绍memcached的应用知识和应用程序兼容性等内容。</p></div></div><img src ="http://www.cppblog.com/API/aggbug/192976.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/API/" target="_blank">C++技术中心</a> 2012-10-08 09:39 <a href="http://www.cppblog.com/API/archive/2012/10/08/192976.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows 查看连接数</title><link>http://www.cppblog.com/API/archive/2012/08/20/187785.html</link><dc:creator>C++技术中心</dc:creator><author>C++技术中心</author><pubDate>Mon, 20 Aug 2012 11:54:00 GMT</pubDate><guid>http://www.cppblog.com/API/archive/2012/08/20/187785.html</guid><wfw:comment>http://www.cppblog.com/API/comments/187785.html</wfw:comment><comments>http://www.cppblog.com/API/archive/2012/08/20/187785.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/API/comments/commentRss/187785.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/API/services/trackbacks/187785.html</trackback:ping><description><![CDATA[netstat -ant | find "9339" &gt; c:\aa.txt<br /><strong style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.2000007629395px; background-color: #efefef;">netstat -aon|findstr "9050"</strong><img src ="http://www.cppblog.com/API/aggbug/187785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/API/" target="_blank">C++技术中心</a> 2012-08-20 19:54 <a href="http://www.cppblog.com/API/archive/2012/08/20/187785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CodeLite  出现中文乱码问题</title><link>http://www.cppblog.com/API/archive/2012/03/28/169283.html</link><dc:creator>C++技术中心</dc:creator><author>C++技术中心</author><pubDate>Wed, 28 Mar 2012 08:13:00 GMT</pubDate><guid>http://www.cppblog.com/API/archive/2012/03/28/169283.html</guid><wfw:comment>http://www.cppblog.com/API/comments/169283.html</wfw:comment><comments>http://www.cppblog.com/API/archive/2012/03/28/169283.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/API/comments/commentRss/169283.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/API/services/trackbacks/169283.html</trackback:ping><description><![CDATA[<div>1.选择工程-&gt;setting-&gt;Common Settings-&gt;Compiler-&gt;<br />的c++ Compiler options 与c Compiler Option中加入<br /><span style="color: #ff0000">-fexec-charset=GBK;</span></div><img src ="http://www.cppblog.com/API/aggbug/169283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/API/" target="_blank">C++技术中心</a> 2012-03-28 16:13 <a href="http://www.cppblog.com/API/archive/2012/03/28/169283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个封装好的线程类</title><link>http://www.cppblog.com/API/archive/2011/03/11/141563.html</link><dc:creator>C++技术中心</dc:creator><author>C++技术中心</author><pubDate>Fri, 11 Mar 2011 06:45:00 GMT</pubDate><guid>http://www.cppblog.com/API/archive/2011/03/11/141563.html</guid><wfw:comment>http://www.cppblog.com/API/comments/141563.html</wfw:comment><comments>http://www.cppblog.com/API/archive/2011/03/11/141563.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/API/comments/commentRss/141563.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/API/services/trackbacks/141563.html</trackback:ping><description><![CDATA[一.创建线程函数<br>&nbsp;&nbsp;&nbsp;&nbsp; 常用的创建线程的函数是CreateThread,还有MFC中的AfxBeginThread方法.另一种函数是_beginthreadex,<br>其实它在内部调用了CreateThread，在调用之前_beginthreadex做了很多的工作，从而使得它比CreateThread更<br>安全.所以一般使用_beginthreadex来创建线程.于是以下使用_beginthreadex函数来创建线程类.<br><br>二.线程类示例<br>1.Thread.h文件如下:<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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">#ifndef&nbsp;_THREAD_H__<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;_THREAD_H__</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">process.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;CThread<br><img id=Codehighlighter1_97_502_Open_Image onclick="this.style.display='none'; Codehighlighter1_97_502_Open_Text.style.display='none'; Codehighlighter1_97_502_Closed_Image.style.display='inline'; Codehighlighter1_97_502_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_97_502_Closed_Image onclick="this.style.display='none'; Codehighlighter1_97_502_Closed_Text.style.display='none'; Codehighlighter1_97_502_Open_Image.style.display='inline'; Codehighlighter1_97_502_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_97_502_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_97_502_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;CThread();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">CThread();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;StartThread();&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">开始线程</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;SuspendThread();&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">挂起线程</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;BOOL&nbsp;Run();&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">线程的入口</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;StopThread();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">等待线程退出再返回</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;unsigned&nbsp;__stdcall&nbsp;start_address(&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;obj);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;m_hthread;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">线程句柄</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;m_hEventSuspend;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">用于标识线程是工作,还是挂起状态</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;m_status;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">线程状态,FALSE表示线程退出状态,TRUE表示未提出状态</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;&nbsp;m_thrdaddr;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000">/*_THREAD_H__*/</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span></div>
<br>2.Thread.cpp文件如下:<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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Thread.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">CThread::CThread()<br><img id=Codehighlighter1_41_275_Open_Image onclick="this.style.display='none'; Codehighlighter1_41_275_Open_Text.style.display='none'; Codehighlighter1_41_275_Closed_Image.style.display='inline'; Codehighlighter1_41_275_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_41_275_Closed_Image onclick="this.style.display='none'; Codehighlighter1_41_275_Closed_Text.style.display='none'; Codehighlighter1_41_275_Open_Image.style.display='inline'; Codehighlighter1_41_275_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_41_275_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_41_275_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;m_hEventSuspend&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;CreateEvent(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,TRUE,FALSE,NULL);//创建事件句柄,且为非激发状态<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;m_status&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;TRUE;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">创建线程</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;m_hthread&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(HANDLE)_beginthreadex(NULL,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,CThread::start_address,</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">m_thrdaddr);</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif"></span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">CThread::</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">CThread()<br><img id=Codehighlighter1_298_358_Open_Image onclick="this.style.display='none'; Codehighlighter1_298_358_Open_Text.style.display='none'; Codehighlighter1_298_358_Closed_Image.style.display='inline'; Codehighlighter1_298_358_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_298_358_Closed_Image onclick="this.style.display='none'; Codehighlighter1_298_358_Closed_Text.style.display='none'; Codehighlighter1_298_358_Open_Image.style.display='inline'; Codehighlighter1_298_358_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_298_358_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_298_358_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(m_hEventSuspend);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(&nbsp;m_hthread&nbsp;);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">BOOL&nbsp;CThread::StartThread()<br><img id=Codehighlighter1_389_426_Open_Image onclick="this.style.display='none'; Codehighlighter1_389_426_Open_Text.style.display='none'; Codehighlighter1_389_426_Closed_Image.style.display='inline'; Codehighlighter1_389_426_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_389_426_Closed_Image onclick="this.style.display='none'; Codehighlighter1_389_426_Closed_Text.style.display='none'; Codehighlighter1_389_426_Open_Image.style.display='inline'; Codehighlighter1_389_426_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_389_426_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_389_426_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;SetEvent(m_hEventSuspend);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">BOOL&nbsp;CThread::SuspendThread()<br><img id=Codehighlighter1_459_498_Open_Image onclick="this.style.display='none'; Codehighlighter1_459_498_Open_Text.style.display='none'; Codehighlighter1_459_498_Closed_Image.style.display='inline'; Codehighlighter1_459_498_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_459_498_Closed_Image onclick="this.style.display='none'; Codehighlighter1_459_498_Closed_Text.style.display='none'; Codehighlighter1_459_498_Open_Image.style.display='inline'; Codehighlighter1_459_498_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_459_498_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_459_498_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;ResetEvent(m_hEventSuspend);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">BOOL&nbsp;CThread::Run()<br><img id=Codehighlighter1_521_537_Open_Image onclick="this.style.display='none'; Codehighlighter1_521_537_Open_Text.style.display='none'; Codehighlighter1_521_537_Closed_Image.style.display='inline'; Codehighlighter1_521_537_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_521_537_Closed_Image onclick="this.style.display='none'; Codehighlighter1_521_537_Closed_Text.style.display='none'; Codehighlighter1_521_537_Open_Image.style.display='inline'; Codehighlighter1_521_537_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_521_537_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_521_537_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;TRUE;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">BOOL&nbsp;CThread::StopThread()<br><img id=Codehighlighter1_567_700_Open_Image onclick="this.style.display='none'; Codehighlighter1_567_700_Open_Text.style.display='none'; Codehighlighter1_567_700_Closed_Image.style.display='inline'; Codehighlighter1_567_700_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_567_700_Closed_Image onclick="this.style.display='none'; Codehighlighter1_567_700_Closed_Text.style.display='none'; Codehighlighter1_567_700_Open_Image.style.display='inline'; Codehighlighter1_567_700_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_567_700_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_567_700_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;m_status&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;FALSE;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">将线程状态置为退出</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;StartThread();&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">把线程唤醒,以免挂死在休眠处</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;WaitForSingleObject(m_hthread,INFINITE);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">等待线程退出</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;TRUE;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">unsigned&nbsp;__stdcall&nbsp;CThread::start_address(&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;obj)<br><img id=Codehighlighter1_758_982_Open_Image onclick="this.style.display='none'; Codehighlighter1_758_982_Open_Text.style.display='none'; Codehighlighter1_758_982_Closed_Image.style.display='inline'; Codehighlighter1_758_982_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_758_982_Closed_Image onclick="this.style.display='none'; Codehighlighter1_758_982_Closed_Text.style.display='none'; Codehighlighter1_758_982_Open_Image.style.display='inline'; Codehighlighter1_758_982_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_758_982_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_758_982_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;CThread</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pthread&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;static_cast</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">CThread</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">(obj);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(pthread</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">m_status)<br><img id=Codehighlighter1_836_950_Open_Image onclick="this.style.display='none'; Codehighlighter1_836_950_Open_Text.style.display='none'; Codehighlighter1_836_950_Closed_Image.style.display='inline'; Codehighlighter1_836_950_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_836_950_Closed_Image onclick="this.style.display='none'; Codehighlighter1_836_950_Closed_Text.style.display='none'; Codehighlighter1_836_950_Open_Image.style.display='inline'; Codehighlighter1_836_950_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_836_950_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_836_950_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WaitForSingleObject(pthread</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">m_hEventSuspend,INFINITE);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">控制挂起，运行<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">如果自动退出</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">pthread</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Run())<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;_endthreadex(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span></div>
<br>三.线程类的使用<br>1. 新建一个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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Thread.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">conio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;CMyThread:</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;CThread<br><img id=Codehighlighter1_115_197_Open_Image onclick="this.style.display='none'; Codehighlighter1_115_197_Open_Text.style.display='none'; Codehighlighter1_115_197_Closed_Image.style.display='inline'; Codehighlighter1_115_197_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_115_197_Closed_Image onclick="this.style.display='none'; Codehighlighter1_115_197_Closed_Text.style.display='none'; Codehighlighter1_115_197_Open_Image.style.display='inline'; Codehighlighter1_115_197_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_115_197_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_115_197_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;Run()<br><img id=Codehighlighter1_138_195_Open_Image onclick="this.style.display='none'; Codehighlighter1_138_195_Open_Text.style.display='none'; Codehighlighter1_138_195_Closed_Image.style.display='inline'; Codehighlighter1_138_195_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_138_195_Closed_Image onclick="this.style.display='none'; Codehighlighter1_138_195_Closed_Text.style.display='none'; Codehighlighter1_138_195_Open_Image.style.display='inline'; Codehighlighter1_138_195_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_138_195_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_138_195_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">hello!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">5000</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;TRUE;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></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,</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">argv[])<br><img id=Codehighlighter1_233_497_Open_Image onclick="this.style.display='none'; Codehighlighter1_233_497_Open_Text.style.display='none'; Codehighlighter1_233_497_Closed_Image.style.display='inline'; Codehighlighter1_233_497_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_233_497_Closed_Image onclick="this.style.display='none'; Codehighlighter1_233_497_Closed_Text.style.display='none'; Codehighlighter1_233_497_Open_Image.style.display='inline'; Codehighlighter1_233_497_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_233_497_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_233_497_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">创建线程</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CMyThread&nbsp;mythread;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">让线程启动</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;mythread.StartThread();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">按任意键,线程挂起</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;_getch();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;mythread.SuspendThread();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">thread&nbsp;suspend</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">接任意键,线程停止</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;_getch();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;mythread.StopThread();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">thread&nbsp;stop</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">按任意键,程序退出</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;_getch();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span></div>
<br>
<img src ="http://www.cppblog.com/API/aggbug/141563.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/API/" target="_blank">C++技术中心</a> 2011-03-11 14:45 <a href="http://www.cppblog.com/API/archive/2011/03/11/141563.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>静态链接库与动态链接库使用详解</title><link>http://www.cppblog.com/API/archive/2011/03/10/141506.html</link><dc:creator>C++技术中心</dc:creator><author>C++技术中心</author><pubDate>Thu, 10 Mar 2011 07:48:00 GMT</pubDate><guid>http://www.cppblog.com/API/archive/2011/03/10/141506.html</guid><wfw:comment>http://www.cppblog.com/API/comments/141506.html</wfw:comment><comments>http://www.cppblog.com/API/archive/2011/03/10/141506.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/API/comments/commentRss/141506.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/API/services/trackbacks/141506.html</trackback:ping><description><![CDATA[<span style="COLOR: red">一.静态库<br></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用通俗的话讲,静态库就是将代码编译到一个二进制文件下(通常扩展名为.LIB).然后客户<br>端调用程序,只需要包含相关的.h文件及LIB库文件一起链接到exe文件中.可执行程序发布后,不<br>再需要该.lib文件了.<br><br><span style="COLOR: red">二.动态库<br></span>&nbsp;&nbsp; 最终将编译出.lib与.dll文件. 注意.lib文件与上面的静态库虽然扩展名相同,但有本质的<br>&nbsp;&nbsp; 区别.动态库中的lib文件是动态库的引入库. 该引入库包含被DLL导出的函数和变量的"符号<br>&nbsp;&nbsp; 名".而静态库中的.lib包含了函数和数据,动态库的函数和数据是编译到.dll中.动态链接库调<br>&nbsp;&nbsp; 用方式分为隐式调用与显示调用(也称静态调用与动态调用)。<br><br><span style="COLOR: red">三.静态库的使用<br></span><span style="COLOR: #0000ff">1.下面来看看如何生成一个静态库<br></span>&nbsp;&nbsp; <br>&nbsp;&nbsp; (1)新建静态库工程,新建DllStaticLib.h及新建DllStaticLib.cpp文件<br>&nbsp;&nbsp; (2)DllStaticLib.h代码如下：<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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;#ifndef&nbsp;_DLL_STATIC_LIB_H__<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;_DLL_STATIC_LIB_H__</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img id=Codehighlighter1_76_109_Open_Image onclick="this.style.display='none'; Codehighlighter1_76_109_Open_Text.style.display='none'; Codehighlighter1_76_109_Closed_Image.style.display='inline'; Codehighlighter1_76_109_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_76_109_Closed_Image onclick="this.style.display='none'; Codehighlighter1_76_109_Closed_Text.style.display='none'; Codehighlighter1_76_109_Open_Image.style.display='inline'; Codehighlighter1_76_109_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif">&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">extern</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">"</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_76_109_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_76_109_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;add(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;x,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;y);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000">/*_DLL_STATIC_LIB_H__*/</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span></div>
&nbsp;&nbsp; (3)DllStaticLib.cpp代码如下:<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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">DllStaticLib.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">stdafx.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;add(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;x,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;y)<br><img id=Codehighlighter1_80_102_Open_Image onclick="this.style.display='none'; Codehighlighter1_80_102_Open_Text.style.display='none'; Codehighlighter1_80_102_Closed_Image.style.display='inline'; Codehighlighter1_80_102_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_80_102_Closed_Image onclick="this.style.display='none'; Codehighlighter1_80_102_Closed_Text.style.display='none'; Codehighlighter1_80_102_Open_Image.style.display='inline'; Codehighlighter1_80_102_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif">&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_80_102_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_80_102_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;x</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">y;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>(4)最终生成DllStaticLib.lib静态库文件<br><span style="COLOR: #0000ff">2.调用静态库<br></span>&nbsp; (1)现在只要使用DllStaticLib.lib,DllStaticLib.h文件.<br>&nbsp;&nbsp;&nbsp;&nbsp; (注意让VC能搜索到该文件,设置VC相关的包含目录与库目录.<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; (2)调用代码如下:<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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">stdafx.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">conio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">DllStaticLib.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">要设置VC包含目录,以便编译时能找到头文件<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">要设置VC库目录,以便编译链接时可以找到该DllStaticLib.lib</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #000000">#pragma&nbsp;comment(lib,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">DllStaticLib.lib</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></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><img id=Codehighlighter1_203_255_Open_Image onclick="this.style.display='none'; Codehighlighter1_203_255_Open_Text.style.display='none'; Codehighlighter1_203_255_Closed_Image.style.display='inline'; Codehighlighter1_203_255_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_203_255_Closed_Image onclick="this.style.display='none'; Codehighlighter1_203_255_Closed_Text.style.display='none'; Codehighlighter1_203_255_Open_Image.style.display='inline'; Codehighlighter1_203_255_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_203_255_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_203_255_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,add(</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">));<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;_getch();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span></div>
<br><span style="COLOR: red">四. 动态链接库的使用<br></span><span style="COLOR: #0000ff">1.生成动态链接库<br></span>&nbsp; (1)新建动态链接库工程,加入TestDll.h及TestDll.cpp文件<br>&nbsp; (2)TestDll.h代码如下:<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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">#ifndef&nbsp;_TEST_DLL_H__<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;_TEST_DLL_H__</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#ifdef&nbsp;TESTDLL_EXPORTS<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;TESTDLL_API&nbsp;__declspec(dllexport)</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#else</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;TESTDLL_API&nbsp;__declspec(dllimport)</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">extern</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;TESTDLL_API&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sum(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;x,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;y);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000">/*_TEST_DLL_H__*/</span></div>
<br>&nbsp;(3)TestDll.cpp代码如下:<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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">TestDll.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sum(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;x,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;y)<br><img id=Codehighlighter1_43_58_Open_Image onclick="this.style.display='none'; Codehighlighter1_43_58_Open_Text.style.display='none'; Codehighlighter1_43_58_Closed_Image.style.display='inline'; Codehighlighter1_43_58_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_43_58_Closed_Image onclick="this.style.display='none'; Codehighlighter1_43_58_Closed_Text.style.display='none'; Codehighlighter1_43_58_Open_Image.style.display='inline'; Codehighlighter1_43_58_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_43_58_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_43_58_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;x</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">y;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span></div>
<br>&nbsp; (3)注意,将工程中设置属性定义TESTDLL_EXPORTS宏,以便确定该工程为DLL导出<br>&nbsp; (4)最终生成TestDll.lib及TestDll.dll文件<br><br><span style="COLOR: #0000ff">2.隐式调用Dll库<br></span>&nbsp; (1)新建win32控制台工程,加入DllClient.cpp<br>&nbsp; (2)示例代码如下:<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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">conio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">TestDll.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">要设置VC包含目录,以便编译时能找到头文件</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">要设置VC库目录,以便编译链接时可以找到该DllStaticLib.lib</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #000000">#pragma&nbsp;&nbsp;comment(lib,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">TestDll.lib</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></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,</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">argv[])<br><img id=Codehighlighter1_216_268_Open_Image onclick="this.style.display='none'; Codehighlighter1_216_268_Open_Text.style.display='none'; Codehighlighter1_216_268_Closed_Image.style.display='inline'; Codehighlighter1_216_268_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_216_268_Closed_Image onclick="this.style.display='none'; Codehighlighter1_216_268_Closed_Text.style.display='none'; Codehighlighter1_216_268_Open_Image.style.display='inline'; Codehighlighter1_216_268_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_216_268_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_216_268_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,sum(</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">));<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;_getch();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span></div>
<p>(3)说明,隐式调用需要lib文件,但是exe编译后,就不再需要lib,只需要dll文件即可.<br>&nbsp;&nbsp;&nbsp;&nbsp; 以下显式调用不需要lib文件,只需要提供dll文件.随exe运行与结束装载或释放dll文件.</p>
<p><span style="COLOR: #0000ff">3.显式调用Dll库<br></span>(1)同上新建win32工程.加入cpp文件,代码如下:<br></p>
<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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">conio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">typedef&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;FUN_SUM(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;x,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;y);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></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,</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">argv[])<br><img id=Codehighlighter1_149_479_Open_Image onclick="this.style.display='none'; Codehighlighter1_149_479_Open_Text.style.display='none'; Codehighlighter1_149_479_Closed_Image.style.display='inline'; Codehighlighter1_149_479_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_149_479_Closed_Image onclick="this.style.display='none'; Codehighlighter1_149_479_Closed_Text.style.display='none'; Codehighlighter1_149_479_Open_Image.style.display='inline'; Codehighlighter1_149_479_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_149_479_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_149_479_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;HINSTANCE&nbsp;hDll;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">DLL句柄</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;hDll&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;LoadLibrary(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">TestDll.dll</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(hDll&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;NULL)<br><img id=Codehighlighter1_235_409_Open_Image onclick="this.style.display='none'; Codehighlighter1_235_409_Open_Text.style.display='none'; Codehighlighter1_235_409_Closed_Image.style.display='inline'; Codehighlighter1_235_409_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_235_409_Closed_Image onclick="this.style.display='none'; Codehighlighter1_235_409_Closed_Text.style.display='none'; Codehighlighter1_235_409_Open_Image.style.display='inline'; Codehighlighter1_235_409_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_235_409_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_235_409_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FUN_SUM&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">sum&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(FUN_SUM</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)GetProcAddress(hDll,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">sum</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(sum)<br><img id=Codehighlighter1_305_338_Open_Image onclick="this.style.display='none'; Codehighlighter1_305_338_Open_Text.style.display='none'; Codehighlighter1_305_338_Closed_Image.style.display='inline'; Codehighlighter1_305_338_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_305_338_Closed_Image onclick="this.style.display='none'; Codehighlighter1_305_338_Closed_Text.style.display='none'; Codehighlighter1_305_338_Open_Image.style.display='inline'; Codehighlighter1_305_338_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_305_338_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_305_338_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">sum)(</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_349_384_Open_Image onclick="this.style.display='none'; Codehighlighter1_349_384_Open_Text.style.display='none'; Codehighlighter1_349_384_Closed_Image.style.display='inline'; Codehighlighter1_349_384_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_349_384_Closed_Image onclick="this.style.display='none'; Codehighlighter1_349_384_Closed_Text.style.display='none'; Codehighlighter1_349_384_Open_Image.style.display='inline'; Codehighlighter1_349_384_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_349_384_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_349_384_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">获取sum函数指针失败!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FreeLibrary(hDll);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_418_455_Open_Image onclick="this.style.display='none'; Codehighlighter1_418_455_Open_Text.style.display='none'; Codehighlighter1_418_455_Closed_Image.style.display='inline'; Codehighlighter1_418_455_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_418_455_Closed_Image onclick="this.style.display='none'; Codehighlighter1_418_455_Closed_Text.style.display='none'; Codehighlighter1_418_455_Open_Image.style.display='inline'; Codehighlighter1_418_455_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_418_455_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_418_455_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">装载TestDll.dll失败!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;_getch();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span></div>
<p><br>(2)显式链接在程序运行中可以把DLL的内存动态映射到调用进程的地址空间。释放可按需释放,使用更灵活.</p>
<img src ="http://www.cppblog.com/API/aggbug/141506.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/API/" target="_blank">C++技术中心</a> 2011-03-10 15:48 <a href="http://www.cppblog.com/API/archive/2011/03/10/141506.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内存映射文件</title><link>http://www.cppblog.com/API/archive/2011/03/09/141423.html</link><dc:creator>C++技术中心</dc:creator><author>C++技术中心</author><pubDate>Wed, 09 Mar 2011 07:05:00 GMT</pubDate><guid>http://www.cppblog.com/API/archive/2011/03/09/141423.html</guid><wfw:comment>http://www.cppblog.com/API/comments/141423.html</wfw:comment><comments>http://www.cppblog.com/API/archive/2011/03/09/141423.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/API/comments/commentRss/141423.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/API/services/trackbacks/141423.html</trackback:ping><description><![CDATA[<p>一.内存映射文件技术作用<br>1.使用内存映射文件来访问磁盘上的数据文件。这使你可以不必对文件执行 I / O操作，并且可以不必对文件内容进行缓存.<br>2.可以使用内存映射文件，使同一台计算机上运行的多个进程能够相互之间共享数据。windows确实提供了其他一些方法，<br>&nbsp;&nbsp;&nbsp; 以便在进程之间进行数据通信，但是这些方法都是使用内存映射文件来实现的，诸如使用SendMessage或者PostMessage，<br>&nbsp;&nbsp;&nbsp; 都在内部使用了内存映射文件.这使得内存映射文件成为单个计算机上的多个进程互相进行通信的最有效的方法。<br><br>二.相当函数介绍<br><span style="COLOR: red">&nbsp;&nbsp;1. CreateFile函数<br></span>&nbsp; (1)作用:创建或打开下列对象，并返回一个可以用来访问这些对象的句柄(可以打开:文件,管道等)<br>&nbsp;&nbsp;(2)函数原型:<br>&nbsp;&nbsp; HANDLE CreateFile(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPCTSTR lpFileName,&nbsp;&nbsp;&nbsp; //指向文件名的指针<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwDesiredAccess,&nbsp;&nbsp;&nbsp; //访问模式（写/读）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwShareMode,&nbsp;&nbsp;&nbsp; //共享模式<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;DWORD dwCreationDisposition,&nbsp;&nbsp; //如何创建<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;DWORD dwFlagsAndAttributes,&nbsp;&nbsp; //文件属性<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HANDLE hTemplateFile&nbsp;&nbsp;&nbsp; //用于复制文件句柄<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<br>&nbsp; (3)参数介绍<br>&nbsp;&nbsp; <img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/api/Image.jpg" width=1049 height=650><br>(4)返回值<br>&nbsp;&nbsp;&nbsp;&nbsp; 如执行成功，则返回文件句柄。INVALID_HANDLE_VALUE表示出错，会设置GetLastError。即使函数成功，<br>&nbsp;&nbsp;&nbsp;&nbsp; 但若文件存在，且指定了CREATE_ALWAYS 或 OPEN_ALWAYS，GetLastError也会设为ERROR_ALREADY_EXISTS<br><br><br><span style="COLOR: red">2.CreateFileMapping <br></span>(1)为指定文件创建一个有名或无名的文件映象<br>(2)函数原型<br>HANDLE CreateFileMapping(<br>&nbsp; HANDLE hFile,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 映射文件的句柄<br>&nbsp; LPSECURITY_ATTRIBUTES lpFileMappingAttributes,<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; // 安全描述符指针<br>&nbsp; DWORD flProtect,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 对映射对象的保护<br>&nbsp; DWORD dwMaximumSizeHigh,&nbsp;&nbsp; // 对象最大长度的高32位<br>&nbsp; DWORD dwMaximumSizeLow,&nbsp;&nbsp;&nbsp; // 对象最大长度的低32位<br>&nbsp; LPCTSTR lpName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 文件内存映射对象的名字<br>);</p>
<p>(3)参数说明<br>hFile：映射文件的句柄，文件的打开模式必须与flProtect参数指定的相一致；如果这个参数值为0xFFFFFFFF，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那么必须在dwMaximumSizeHigh和dwMaximumSizeLow参数中指定映射对象的大小。并且将在操作系统<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虚拟内存页面替换文件中创建文件映射对象，而不是使用磁盘文件，同时必须给出这个映射对象的大小。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 文件映射对象通过副本，遗传或名字来共享。<br>lpFileMappingAttributes：安全描述符指针，决定返回句柄是否能被子进程继承，如果是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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 继承。WinNt中，如果是NULL，那么文件映射对象得到一个默认的安全描述符。<br>flProtect：为得到的文件试图指定保护模式，可以被设置为下列值：<br>&nbsp;&nbsp;&nbsp;&nbsp; PAGE_READONLY ：只读属性，并且hFile对应的文件必须以GENERIC_READ形式打开。<br>&nbsp;&nbsp;&nbsp;&nbsp; PAGE_READWRITE：可读可写属性，并且hFile对应的文件必须以GENERIC_READ 和 GENERIC_WRITE形式打开。<br>&nbsp;&nbsp;&nbsp; PAGE_WRITECOPY：对可写区域复制后操作，并且hFile对应的文件必须以GENERIC_READ 和 GENERIC_WRITE形式打开。</p>
<p>dwMaximumSizeHigh，dwMaximumSizeLow：如果这两个参数为0，则文件映射对象的最大长度等于hFile指定的文件长度<br>lpName：文件映射对象的名字，如果这个名字已存在，则按照flProtect指定的来处理映射对象。如果此参数为空，则创<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 建一个无名字的文件映射对象。如果此参数的名字与系统事件的名字相同，则函数执行失败，GetLastError返回<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ERROR_INVALID_HANDLE；</p>
<p>(4)返回值<br>&nbsp;&nbsp;&nbsp;&nbsp; 数调用成功返回文件映射对象的句柄，如果文件映射对象已经存在则返回原有映射对象的句柄，GetLastError返回<br>&nbsp;&nbsp;&nbsp;&nbsp; ERROR_ALREADY_EXISTS。函数执行失败返回Null<br><br></p>
<p><span style="COLOR: red">3. MapViewOfFile<br></span>(1)在调用进程的地址空间映射一个文件视图<br>(2)函数原型<br>LPVOID MapViewOfFile(<br>&nbsp; HANDLE hFileMappingObject,&nbsp; // 已创建的文件映射对象句柄<br>&nbsp; DWORD dwDesiredAccess,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 访问模式<br>&nbsp; DWORD dwFileOffsetHigh,&nbsp;&nbsp;&nbsp;&nbsp; // 文件偏移的高32位<br>&nbsp; DWORD dwFileOffsetLow,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 文件偏移的低32位<br>&nbsp; DWORD dwNumberOfBytesToMap&nbsp; // 映射视图的大小<br>);<br>(3)参数<br>&nbsp;&nbsp;&nbsp; hFileMappingObject： 由CreateFileMapping 或 OpenFileMapping 返回的文件映射对象句柄。<br>&nbsp;&nbsp;&nbsp; dwDesiredAccess：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 映射视图的访问模式，与创建文件映射对象的保护模式flProtect有关，可以被设置为下列值：<br>&nbsp;&nbsp;&nbsp; FILE_MAP_WRITE：&nbsp; 一个可读写属性的文件视图被创建，保护模式为PAGE_READWRITE <br>&nbsp;&nbsp;&nbsp; FILE_MAP_READ ：&nbsp; 一个只读属性的文件视图被创建，保护模式为PAGE_READWRITE 或 PAGE_READONLY <br>&nbsp;&nbsp;&nbsp; FILE_MAP_ALL_ACCESS：与FILE_MAP_WRITE模式相同<br>&nbsp;&nbsp;&nbsp; FILE_MAP_COPY：&nbsp; 保护模式为PAGE_WRITECOPY时，得到一个视图文件，当你对视图文件写操作时，页面自动<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 交换，并且你所做的修改不会损坏原始数据资料。<br>&nbsp; dwNumberOfBytesToMap：映射文件部分的大小，如果为0，则映射整个文件。 <br>(4)返回值：如果成功返回返回映射视图的起始地址，如果失败返回NULL<br><br></p>
<p><span style="COLOR: red">4.UnmapViewOfFile<br></span>(1)删除文件的映射视图<br>(2)函数原型<br>BOOL UnmapViewOfFile(<br>&nbsp; LPCVOID lpBaseAddress&nbsp;&nbsp; // 映射视图起始地址<br>);<br>(3)参数<br>lpBaseAddress：映射视图起始地址，由 MapViewOfFile 函数 MapViewOfFileEx产生</p>
<p>(4)返回值:如果调用成功返回非零，并且所有指定地址内的脏页面会被写入硬盘。调用失败返回零。</p>
<p><br><br><span style="COLOR: red">5.FlushViewOfFile <br></span>(1)把文件映射视图中的修改的内容或全部写回到磁盘文件中<br>(2)函数原型<br>BOOL FlushViewOfFile(<br>&nbsp; LPCVOID lpBaseAddress,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 修改内容的起始地址<br>&nbsp; DWORD dwNumberOfBytesToFlush // 修改的字节数目<br>);<br>(3)返回值:函数执行成功返回非零。<br><br></p>
<p><span style="COLOR: red">6.MapViewOfFileEx <br></span>(1)在调用进程的地址空间映射一个文件视图，并且允许调用进程为映射视图指定特殊的内存地址 <br>(2)函数原型:<br>LPVOID MapViewOfFileEx(<br>&nbsp; HANDLE hFileMappingObject,&nbsp; // 文件映射对象的句柄<br>&nbsp; DWORD dwDesiredAccess,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 访问模式<br>&nbsp; DWORD dwFileOffsetHigh,&nbsp;&nbsp;&nbsp;&nbsp; // 文件偏移的高32位<br>&nbsp; DWORD dwFileOffsetLow,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 文件偏移的低32位<br>&nbsp; DWORD dwNumberOfBytesToMap, // 映射视图的大小<br>&nbsp; LPVOID lpBaseAddress&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 指定映射视图的其实内存地址<br>);<br>注意：<br>与MapViewOfFile用法相同，但是如果指定的内存地址空间大小不够，则函数执行失败。<br><br><br><span style="COLOR: red">7.OpenFileMapping <br></span>(1)打开一个已命名的文件映射对象<br>(2)函数原型<br>HANDLE OpenFileMapping(<br>&nbsp; DWORD dwDesiredAccess,&nbsp; // 访问模式<br>&nbsp; BOOL bInheritHandle,&nbsp;&nbsp;&nbsp; // 继承标志<br>&nbsp; LPCTSTR lpName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 文件映射对象名指针<br>);<br>(3)参数<br>dwDesiredAccess：访问模式与MapViewOfFile中的访问模式相同。<br>bInheritHandle：继承标志，是否可以被一个新的进程继承使用，如果为TRUE，就可以被一个新进程继承句柄。<br>(4)返回值<br>&nbsp;成功返回一个已命名的文件映射对象，失败返回NULL。<br><br><br>三. 以下是简单的操作示例<br></p>
<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"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">#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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">conio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdlib.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></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,</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;argv[])<br><img id=Codehighlighter1_111_1164_Open_Image onclick="this.style.display='none'; Codehighlighter1_111_1164_Open_Text.style.display='none'; Codehighlighter1_111_1164_Closed_Image.style.display='inline'; Codehighlighter1_111_1164_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_111_1164_Closed_Image onclick="this.style.display='none'; Codehighlighter1_111_1164_Closed_Text.style.display='none'; Codehighlighter1_111_1164_Open_Image.style.display='inline'; Codehighlighter1_111_1164_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_111_1164_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_111_1164_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hFile;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;OFSTRUCT&nbsp;opBuf;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hMapfile;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hMapview;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">recv;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">1.创建或打开文件</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;hFile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;::CreateFile(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">D:\\MapFileTest.txt</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;&nbsp;GENERIC_READ&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;GENERIC_WRITE,&nbsp;FILE_SHARE_READ</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">FILE_SHARE_WRITE,&nbsp;NULL,OPEN_ALWAYS,&nbsp;FILE_ATTRIBUTE_NORMAL,&nbsp;NULL);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(hFile</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_384_433_Open_Image onclick="this.style.display='none'; Codehighlighter1_384_433_Open_Text.style.display='none'; Codehighlighter1_384_433_Closed_Image.style.display='inline'; Codehighlighter1_384_433_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_384_433_Closed_Image onclick="this.style.display='none'; Codehighlighter1_384_433_Closed_Text.style.display='none'; Codehighlighter1_384_433_Open_Image.style.display='inline'; Codehighlighter1_384_433_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_384_433_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_384_433_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">open&nbsp;file&nbsp;failed!\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&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">1</span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">2.为指定文件创建一个有名的文件映象</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;hMapfile</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">CreateFileMapping((HANDLE)hFile,NULL,PAGE_READWRITE,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MapTest</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(hMapfile</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">NULL)<br><img id=Codehighlighter1_558_610_Open_Image onclick="this.style.display='none'; Codehighlighter1_558_610_Open_Text.style.display='none'; Codehighlighter1_558_610_Closed_Image.style.display='inline'; Codehighlighter1_558_610_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_558_610_Closed_Image onclick="this.style.display='none'; Codehighlighter1_558_610_Closed_Text.style.display='none'; Codehighlighter1_558_610_Open_Image.style.display='inline'; Codehighlighter1_558_610_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_558_610_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_558_610_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">mapping&nbsp;file&nbsp;failed!\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&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">1</span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">关闭文件句柄</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle((HANDLE)hFile);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;hFile</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">3.在调用进程的地址空间映射一个文件视图</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;hMapview</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">MapViewOfFile(hMapfile,FILE_MAP_WRITE,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(hMapview</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">NULL)<br><img id=Codehighlighter1_764_816_Open_Image onclick="this.style.display='none'; Codehighlighter1_764_816_Open_Text.style.display='none'; Codehighlighter1_764_816_Closed_Image.style.display='inline'; Codehighlighter1_764_816_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_764_816_Closed_Image onclick="this.style.display='none'; Codehighlighter1_764_816_Closed_Text.style.display='none'; Codehighlighter1_764_816_Open_Image.style.display='inline'; Codehighlighter1_764_816_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_764_816_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_764_816_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">mapping&nbsp;view&nbsp;failed!\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&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">1</span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">往文件映射视图中写入数据</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;recv</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)hMapview;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Mapping&nbsp;view's&nbsp;content&nbsp;is&nbsp;:%.10s&nbsp;\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,recv);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;strcpy(recv,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">abc</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">把文件映射视图中的修改的内容或全部写回到磁盘文件中</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;FlushViewOfFile(recv,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">4.删除文件的映射视图</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Mapping&nbsp;view's&nbsp;content&nbsp;is&nbsp;:%.10s&nbsp;\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,recv);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;UnmapViewOfFile(hMapview);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">关闭文件映象句柄</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hMapfile);<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;hMapfile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;_getch();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&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><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span></div>
<img src ="http://www.cppblog.com/API/aggbug/141423.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/API/" target="_blank">C++技术中心</a> 2011-03-09 15:05 <a href="http://www.cppblog.com/API/archive/2011/03/09/141423.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>