<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type='text/xsl' href='http://flipcode.spaces.live.com/mmm2008-05-17_13.22/rsspretty.aspx?rssquery=en-US;http%3a%2f%2fflipcode.spaces.live.com%2fcategory%2f%e7%bc%96%e7%a8%8b%e5%a4%a9%e5%9c%b0%2ffeed.rss' version='1.0'?><rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:msn="http://schemas.microsoft.com/msn/spaces/2005/rss" xmlns:live="http://schemas.microsoft.com/live/spaces/2006/rss" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>飘零风雨亭: 编程天地</title><description /><link>http://flipcode.spaces.live.com/?_c11_BlogPart_BlogPart=blogview&amp;_c=BlogPart&amp;partqs=cat%25E7%25BC%2596%25E7%25A8%258B%25E5%25A4%25A9%25E5%259C%25B0</link><language>en-US</language><pubDate>Mon, 23 Jun 2008 08:31:31 GMT</pubDate><lastBuildDate>Mon, 23 Jun 2008 08:31:31 GMT</lastBuildDate><generator>Microsoft Spaces v1.1</generator><docs>http://www.rssboard.org/rss-specification</docs><ttl>60</ttl><cf:parentRSS>http://flipcode.spaces.live.com/blog/feed.rss</cf:parentRSS><live:type>blogcategory</live:type><live:identity><live:id>-8189920746979949719</live:id><live:alias>flipcode</live:alias></live:identity><cf:listinfo><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="typelabel" label="Type" /><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="tag" label="Tag" /><cf:group element="category" label="Category" /><cf:sort element="pubDate" label="Date" data-type="date" default="true" /><cf:sort element="title" label="Title" data-type="string" /><cf:sort ns="http://purl.org/rss/1.0/modules/slash/" element="comments" label="Comments" data-type="number" /></cf:listinfo><item><title>Symbol Paths(转)</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1114.entry</link><description>&lt;div&gt;Symbol Paths(转)&lt;/div&gt;
&lt;div&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms680689(VS.85).aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms680689(VS.85).aspx&lt;/a&gt;&lt;br&gt;The library uses the symbol search path to locate debug symbols (.dbg file) for .dll, .exe, and .sys files by appending &amp;quot;\symbols&amp;quot; and &amp;quot;\dll&amp;quot; or &amp;quot;\exe&amp;quot; or &amp;quot;\sys&amp;quot; to the path. For example, the typical location of symbol files for .dll files is c:\mysymbols\symbols\dll. For .exe files, the location is c:\mysymbols\symbols\exe.&lt;/div&gt;
&lt;div&gt;To specify where the symbol handler will search disk directories for symbol files, call the SymSetSearchPath function. Alternatively, you can specify a symbol search path in the UserSearchPath parameter of the SymInitialize function.&lt;/div&gt;
&lt;div&gt;The UserSearchPath parameter in SymInitialize and the SearchPath parameter in SymSetSearchPath take a pointer to a null-terminated string that specifies a path, or series of paths separated by a semicolon. The symbol handler uses these paths to search for symbol files. If this parameter is specified as a non-null value, the symbol handler searches only the paths set by the application. If this parameter is NULL, the symbol handler first searches the current working directory of the application, then the system root directory (%windir%). If you set the _NT_SYMBOL_PATH or _NT_ALT_SYMBOL_PATH environment variable, the symbol handler searches for symbol files in the following order:&lt;/div&gt;
&lt;div&gt;The current working directory of the application. &lt;br&gt;The _NT_SYMBOL_PATH environment variable. &lt;br&gt;The _NT_ALT_SYMBOL_PATH environment variable. &lt;br&gt;To retrieve the search paths, call the SymGetSearchPath function.&lt;/div&gt;
&lt;div&gt;The search path for program database (.pdb) files is different than the path for debug (.dbg) files. The algorithm is determined by the functionality of the symbol library. By default, Microsoft Visual C/C++ creates Microsoft format symbols, strips them from the image, and places them in a separate .pdb file. Typically, the .pdb file will be located in the directory that contains the executable image. Visual C/C++ embeds the absolute path to the .pdb file in the executable image. If the symbol handler cannot find the .pdb file in that location or if the .pdb file was moved to another directory, the symbol handler will locate the .pdb file using the search path described for .dbg files.&lt;br&gt;&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+Symbol+Paths(%e8%bd%ac)&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1114.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1114.entry</guid><pubDate>Fri, 14 Mar 2008 05:52:14 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1114/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1114.entry#comment</wfw:comment><dcterms:modified>2008-03-14T05:52:14Z</dcterms:modified></item><item><title>fatal error C1900(备忘)</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1102.entry</link><description>&lt;div&gt;fatal error C1900:&lt;/div&gt;
&lt;div&gt;1&amp;gt;------ Build started: Project: sanguo, Configuration: Release Win32 ------&lt;br&gt;1&amp;gt;Linking...&lt;br&gt;1&amp;gt;fatal error C1900: Il mismatch between 'P1' version '20060201' and 'P2' version '20050411'&lt;br&gt;1&amp;gt;LINK : fatal error LNK1257: code generation failed&lt;br&gt;1&amp;gt;Build log was saved at &amp;quot;&lt;a&gt;file://e:\project\sanguo\temp\release\BuildLog.htm&lt;/a&gt;&amp;quot;&lt;br&gt;1&amp;gt;sanguo - 1 error(s), 0 warning(s)&lt;br&gt;&lt;br&gt;上网查了一下估计是链接库打了补丁,而我的没打,造成vc编译版本不一致&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;to fan:&lt;/div&gt;
&lt;div&gt;i can't email to you because your setting's limit.&lt;/div&gt;
&lt;div&gt;fatal error C1900 generate because your compile tools's version different from the lib's(which someone compiled it using another vc2005). &lt;/div&gt;
&lt;div&gt;solve this problem, only need patch the same sp1 or sp2 for your vc2005(i.e. your program and the lib complier's patch must same)!&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+fatal+error+C1900(%e5%a4%87%e5%bf%98)&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1102.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1102.entry</guid><pubDate>Thu, 03 Jan 2008 01:28:44 GMT</pubDate><slash:comments>1</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1102/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1102.entry#comment</wfw:comment><dcterms:modified>2008-03-11T01:27:25Z</dcterms:modified></item><item><title>关于keystate(备忘)</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1101.entry</link><description>&lt;div&gt;1. GetKeyState(VK_CONTROL) &amp;amp; 0x80&lt;/div&gt;
&lt;div&gt; 2. GetAsyncKeyState(VK_LSHIFT) &amp;amp; 0x8000 &lt;br&gt;3. BOOL GetKeyboardState(PBYTE lpKeyState);&lt;br&gt;   if(keystate[VK_RSHIFT])&lt;br&gt;   {&lt;br&gt;      // +++ &lt;br&gt;   }&lt;/div&gt;
&lt;div&gt;区别：&lt;br&gt;1：从windows消息队列中取得键盘消息，返回key status.&lt;br&gt;2：直接侦测键盘的硬件中断，返回key status.&lt;br&gt;3：当从windows消息队列中移除键盘消息时，才返回key status. &lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+%e5%85%b3%e4%ba%8ekeystate(%e5%a4%87%e5%bf%98)&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1101.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1101.entry</guid><pubDate>Thu, 20 Dec 2007 09:07:04 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1101/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1101.entry#comment</wfw:comment><dcterms:modified>2007-12-20T09:07:44Z</dcterms:modified></item><item><title>new抛出异常的一种情况</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1100.entry</link><description>&lt;p&gt;最近修改玩家反馈的bug(dmp文件)
&lt;p&gt;有些内存错误很难查。
&lt;p&gt;在一次无意中发现，在new中抛出异常的一种情况，&lt;br&gt;就是如果前面先new出一个内存，然后你对此内存越界修改（改到后面去了）&lt;br&gt;之后你再new新内存时就可能抛出异常;&lt;br&gt;例如你new char p[100];&lt;br&gt;然后你修改 for( int =0; i&amp;lt;200); ++i){ p[i]=数据; }&lt;br&gt;完成后再new Mydata[10];&lt;br&gt;就可能抛出异常！
&lt;p&gt;以后crash发现new异常时可查看是否上述情况:)
&lt;div&gt;&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+new%e6%8a%9b%e5%87%ba%e5%bc%82%e5%b8%b8%e7%9a%84%e4%b8%80%e7%a7%8d%e6%83%85%e5%86%b5&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1100.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1100.entry</guid><pubDate>Thu, 20 Dec 2007 02:37:52 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1100/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1100.entry#comment</wfw:comment><dcterms:modified>2007-12-20T02:37:52Z</dcterms:modified></item><item><title>程序与lua脚本数据交换(备忘)</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1087.entry</link><description>&lt;div&gt;（这些是以前跟踪分析的，其实挺简单，只是不懂时用来跟踪一遍就完全明白了, 写在这里是为了备忘）&lt;/div&gt;
&lt;div&gt;先给一下lua的值定义:&lt;/div&gt;
&lt;div&gt;lua中的值:&lt;br&gt;TValue{&lt;br&gt;union{gc*,void*,int,bool}; //可回收对象，userlightdata, number, bool&lt;br&gt;tt; //类别&lt;br&gt;};&lt;br&gt;其中gc结构如下:&lt;br&gt;GC{&lt;br&gt;gch; // gc head&lt;br&gt;ts;   //  tstring&lt;br&gt;u;    // user data&lt;br&gt;cl;   // closure&lt;br&gt;h;   // table&lt;br&gt;p;   // proto &lt;br&gt;uv; // upval&lt;br&gt;th;  // theard&lt;br&gt;};&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;一。脚本给程序传表格&lt;/div&gt;
&lt;div&gt;以下代码摘自boswars,用来分析:&lt;br&gt;脚本如下:&lt;/div&gt;
&lt;div&gt;test( {Name = &amp;quot;sprite-mana&amp;quot;, File = &amp;quot;general/mana2.png&amp;quot;, Offset = {0, -1}, Size = {31, 4}} ) // {}中即是表格&lt;/div&gt;
&lt;div&gt;程序如下&lt;/div&gt;
&lt;div&gt;void test(lua_State *l)&lt;br&gt;{&lt;br&gt;  lua_pushnil(l);&lt;br&gt;  while (lua_next(l, i + 1)) {&lt;br&gt;   key = LuaToString(l, -2); // key name&lt;br&gt;   if (!strcmp(key, &amp;quot;Name&amp;quot;)) {&lt;br&gt;    name = LuaToString(l, -1);&lt;br&gt;   } &lt;br&gt;   else if (!strcmp(key, &amp;quot;File&amp;quot;)) {&lt;br&gt;    File = LuaToString(l, -1);&lt;br&gt;   } &lt;br&gt;   else if (!strcmp(key, &amp;quot;Offset&amp;quot;)) {&lt;br&gt;    if (!lua_istable(l, -1) || luaL_getn(l, -1) != 2) {&lt;br&gt;     LuaError(l, &amp;quot;incorrect argument&amp;quot;);&lt;br&gt;    }&lt;br&gt;    lua_rawgeti(l, -1, 1); // offsetX&lt;br&gt;    lua_rawgeti(l, -2, 2); // offsetY&lt;br&gt;    HotX = LuaToNumber(l, -2);&lt;br&gt;    HotY = LuaToNumber(l, -1);&lt;br&gt;    lua_pop(l, 2); // Pop offsetX and Y&lt;br&gt;   } &lt;br&gt;   else if (!strcmp(key, &amp;quot;Size&amp;quot;)) {&lt;br&gt;    if (!lua_istable(l, -1) || luaL_getn(l, -1) != 2) {&lt;br&gt;     LuaError(l, &amp;quot;incorrect argument&amp;quot;);&lt;br&gt;    }&lt;br&gt;    lua_rawgeti(l, -1, 1); // Width&lt;br&gt;    lua_rawgeti(l, -2, 2); // Height&lt;br&gt;    Width = LuaToNumber(l, -2);&lt;br&gt;    Height = LuaToNumber(l, -1);&lt;br&gt;    lua_pop(l, 2); // Pop Width and Height&lt;br&gt;   } &lt;br&gt;   else { // Error.&lt;br&gt;    LuaError(l, &amp;quot;incorrect field '%s' for the DefineSprite.&amp;quot; _C_ key);&lt;br&gt;   }&lt;br&gt;   lua_pop(l, 1); // pop the value;&lt;br&gt;  }&lt;br&gt;}&lt;/div&gt;
&lt;div&gt;lua调用我们的函数void test(lua_State *l)后变成:&lt;br&gt;--- 表&lt;/div&gt;
&lt;div&gt;我们需要先&lt;br&gt;lua_pushnil(l);(把nil作为key)后:&lt;br&gt;--- nil&lt;br&gt;--- 表&lt;/div&gt;
&lt;div&gt;lua_next(l,1)后://1是表的位置,key则是上面的nil&lt;br&gt;--- value // 得到的value&lt;br&gt;--- key   // 得到的key&lt;br&gt;--- 表&lt;/div&gt;
&lt;div&gt;lua_rawgeti(l, -1, 1); //offsetX; 参数-1是table(value是一个表), &lt;br&gt;                       // 1是表的下标, 得到offsetX存在top,并inc top&lt;/div&gt;
&lt;div&gt;--- offsetX&lt;br&gt;--- value&lt;br&gt;--- key&lt;br&gt;--- 表&lt;/div&gt;
&lt;div&gt;lua_rawgeti(l, -2, 1); //offsetY; 参数-2是table(value是一个表)(因为上面压入offsetX,所以变成-2了)&lt;br&gt;                       // 1是表的下标, 得到offsetX存在top,并inc top&lt;br&gt;--- offsetY&lt;br&gt;--- offsetX&lt;br&gt;--- value&lt;br&gt;--- key&lt;br&gt;--- 表&lt;/div&gt;
&lt;div&gt;使用&lt;br&gt;HotX = LuaToNumber(l, -2);&lt;/div&gt;
&lt;div&gt;HotY = LuaToNumber(l, -1);&lt;br&gt;保存得到的offsetX和offsetY&lt;/div&gt;
&lt;div&gt;然后将它们出栈:&lt;br&gt;lua_pop(l, 2); // Pop offsetX and offsetY&lt;br&gt;变成:&lt;br&gt;--- value&lt;br&gt;--- key&lt;br&gt;--- 表&lt;/div&gt;
&lt;div&gt;再将value出栈:&lt;br&gt;lua_pop(l, 1); // pop the value;&lt;br&gt;变成:&lt;br&gt;--- key&lt;br&gt;--- 表&lt;/div&gt;
&lt;div&gt;最后回到while函数继续调用&lt;br&gt;lua_next(l,1)://1是表的位置,key则是上面的key（上一次得到的key）,&lt;br&gt;              //这样些函数数又将会得到下一个key和value放堆栈中&lt;br&gt;变成:&lt;br&gt;--- 下一个value&lt;br&gt;--- 下一个key&lt;br&gt;--- 表              &lt;/div&gt;
&lt;div&gt;如此循环!&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;附：&lt;/div&gt;
&lt;div&gt;这里有一篇类似文章参见:&lt;/div&gt;
&lt;div&gt;使用lua_next()遍历表&lt;/div&gt;
&lt;div&gt;&lt;a href="http://hi.baidu.com/bitbull/blog/item/bc27581eca1886f61bd5768e.html"&gt;http://hi.baidu.com/bitbull/blog/item/bc27581eca1886f61bd5768e.html&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;二。程序生成表格给脚本:&lt;/div&gt;
&lt;div&gt;以下代码也是从boswar拷过来的，挺简单就不分析了&lt;/div&gt;
&lt;div&gt;static int CclFilteredListDirectory(lua_State *l, int type, int mask)&lt;br&gt;{&lt;br&gt; char directory[256];&lt;br&gt; const char *userdir;&lt;br&gt; std::vector&amp;lt;FileList&amp;gt; flp;&lt;br&gt; int n;&lt;br&gt; int i;&lt;br&gt; int j;&lt;br&gt; int pathtype;&lt;/div&gt;
&lt;div&gt; LuaCheckArgs(l, 1);&lt;br&gt; userdir = lua_tostring(l, 1);&lt;br&gt; n = strlen(userdir);&lt;/div&gt;
&lt;div&gt; pathtype = 0; // path relative to stratagus dir&lt;br&gt; if (n &amp;gt; 0 &amp;amp;&amp;amp; *userdir == '~') {&lt;br&gt;  // path relative to user preferences directory&lt;br&gt;  pathtype = 1;&lt;br&gt; }&lt;/div&gt;
&lt;div&gt; // security: disallow all special characters&lt;br&gt; if (strpbrk(userdir, &amp;quot;:*?\&amp;quot;&amp;lt;&amp;gt;|&amp;quot;) != 0 || strstr(userdir, &amp;quot;..&amp;quot;) != 0) {&lt;br&gt;  LuaError(l, &amp;quot;Forbidden directory&amp;quot;);&lt;br&gt; }&lt;/div&gt;
&lt;div&gt; if (pathtype == 1) {&lt;br&gt;  ++userdir;&lt;br&gt;  sprintf(directory, &amp;quot;%s/%s&amp;quot;, UserDirectory.c_str(), userdir);&lt;br&gt; } else {&lt;br&gt;  sprintf(directory, &amp;quot;%s/%s&amp;quot;, StratagusLibPath.c_str(), userdir);&lt;br&gt; }&lt;br&gt; lua_pop(l, 1); &lt;/div&gt;
&lt;div&gt; lua_newtable(l);&lt;br&gt; n = ReadDataDirectory(directory, NULL, flp);&lt;br&gt; for (i = 0, j = 0; i &amp;lt; n; ++i) {&lt;br&gt;  if ((flp[i].type &amp;amp; mask) == type) {&lt;br&gt;   lua_pushnumber(l, j + 1);&lt;br&gt;   lua_pushstring(l, flp[i].name);&lt;br&gt;   lua_settable(l, 1);&lt;br&gt;   ++j;&lt;br&gt;  }&lt;br&gt;  delete[] flp[i].name;&lt;br&gt; }&lt;/div&gt;
&lt;div&gt; return 1;&lt;br&gt;}&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;附：这个可参考:&lt;/div&gt;
&lt;div&gt;Lua 语言和C集成调研小结&lt;/div&gt;
&lt;div&gt;&lt;a href="http://jason.rocklv.net/techdoc/Lua.html"&gt;http://jason.rocklv.net/techdoc/Lua.html&lt;/a&gt;&lt;br&gt;&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+%e7%a8%8b%e5%ba%8f%e4%b8%8elua%e8%84%9a%e6%9c%ac%e6%95%b0%e6%8d%ae%e4%ba%a4%e6%8d%a2(%e5%a4%87%e5%bf%98)&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1087.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1087.entry</guid><pubDate>Wed, 12 Dec 2007 09:47:17 GMT</pubDate><slash:comments>1</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1087/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1087.entry#comment</wfw:comment><dcterms:modified>2007-12-12T10:12:36Z</dcterms:modified></item><item><title>汇编初学者问题合集(转)</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1033.entry</link><description>&lt;div&gt;汇编初学者问题合集(转)     &lt;br&gt;几个简单的汇编初学者问题总结 &lt;br&gt;&lt;a href="http://blog.csdn.net/mydo/archive/2007/09/07/1776304.aspx"&gt;http://blog.csdn.net/mydo/archive/2007/09/07/1776304.aspx&lt;/a&gt;&lt;br&gt; &lt;/div&gt;
&lt;div&gt;0 关于指令时间的问题&lt;br&gt; &lt;/div&gt;
&lt;div&gt;上次有兄弟问关于 指令时间的问题，答复查看 intel 手册是一个办法。&lt;br&gt;但很多人没有那个东东吧！，所以可以用另一招，在编译时加入 /Sc&lt;/div&gt;
&lt;div&gt; 选项：&lt;/div&gt;
&lt;div&gt;ML /Fl /Sc Kinds.asm&lt;/div&gt;
&lt;div&gt;还有有位兄弟问过 为什么 mov ax,offset table 比 lea ax,table 速度&lt;/div&gt;
&lt;div&gt;要快？但到底快到什么程度，恐怕也没法感性认识。下面让偶们来&lt;/div&gt;
&lt;div&gt;看看实际效果:&lt;/div&gt;
&lt;div&gt;首先在源文件 Kinds.asm 中敲入:&lt;/div&gt;
&lt;div&gt;data    segment&lt;br&gt;tabledw?&lt;br&gt;data    ends&lt;/div&gt;
&lt;div&gt;code    segment&lt;br&gt;assume cs:code,ds:data&lt;br&gt;start:&lt;br&gt;push  ds&lt;br&gt;sub    ax,ax&lt;br&gt;push  ax&lt;/div&gt;
&lt;div&gt;mov   ax,data&lt;br&gt;mov   ds,ax&lt;/div&gt;
&lt;div&gt;mov   ax,offset table&lt;br&gt;lea     ax,table&lt;/div&gt;
&lt;div&gt;idiv    table&lt;/div&gt;
&lt;div&gt;retf&lt;br&gt;code    ends&lt;br&gt;     end    start&lt;/div&gt;
&lt;div&gt;保存后，控制台中敲入:&lt;/div&gt;
&lt;div&gt;ML /Fl /Sc Kinds.asm&lt;/div&gt;
&lt;div&gt;完成后，在同一目录下用记事本打开 Kinds.lst 文件:&lt;/div&gt;
&lt;div&gt;0000     datasegment&lt;br&gt;0000 0000     tabledw?&lt;br&gt;0002     dataends&lt;/div&gt;
&lt;div&gt;0000     codesegment&lt;br&gt;assume cs:code,ds:data&lt;br&gt;0000start:&lt;br&gt;0000  10   1Epushds&lt;br&gt;0001   3   2B C0     subax,ax&lt;br&gt;0003  11   50         pushax&lt;/div&gt;
&lt;div&gt;0004   4   B8 ---- Rmovax,data&lt;br&gt;0007   2   8E D8     movds,ax&lt;/div&gt;
&lt;div&gt;0009   4   B8 0000 Rmovax,offset table&lt;br&gt;000C   8   8D 06 0000 R     leaax,table&lt;/div&gt;
&lt;div&gt;0010 177+  F7 3E 0000 R     idivtable&lt;br&gt;     &lt;br&gt;0014  26   CB     retf&lt;br&gt;0015   codeends&lt;br&gt;endstart&lt;/div&gt;
&lt;div&gt;可以清楚地看到 ：&lt;/div&gt;
&lt;div&gt;mov ds,ax 只需要 2个时钟周期&lt;br&gt;mov ax,offset table 需要 4个&lt;br&gt;lea ax,table 则需要 8 个&lt;br&gt;而 idiv table 更是夸张的用到了超过 177 个时钟周期。&lt;/div&gt;
&lt;div&gt;是不是一目了然呢？呵呵!&lt;/div&gt;
&lt;div&gt;&lt;br&gt;1 debug中使用sal指令的问题&lt;br&gt; &lt;/div&gt;
&lt;div&gt;[问题]&lt;/div&gt;
&lt;div&gt;在debug里面使用A指令，输入如下代码：&lt;/div&gt;
&lt;div&gt;***************************&lt;br&gt;MOV AX,0ABC&lt;br&gt;DEC AX&lt;br&gt;AND AX,00FFH&lt;br&gt;MOV CL,4&lt;br&gt;SAL AL,1&lt;/div&gt;
&lt;div&gt;***************************&lt;br&gt;当输入到 sal al，1 时提示error&lt;/div&gt;
&lt;div&gt;[回答]&lt;/div&gt;
&lt;div&gt;shl 与 sal 作用是完全一样的，所以在编译的时候自动将&lt;br&gt;sal 转换成了 shl .使用sal  dubug 不识别，换成shl就搞定了。&lt;br&gt;可以把上述代码编译成 EXE 文件，然后用debug 中 u 指令查看，&lt;/div&gt;
&lt;div&gt;结果 sal 的地方 被换成 shl。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2 看似 ''不可能'' 的汇编问题                             &lt;br&gt; &lt;/div&gt;
&lt;div&gt;[问题]&lt;/div&gt;
&lt;div&gt;怎样用一条指令把BX的内容加上123，放在AX里？&lt;/div&gt;
&lt;div&gt;[回答]&lt;/div&gt;
&lt;div&gt;猛一看起来好像不可能，通常的做法是：&lt;/div&gt;
&lt;div&gt;add   bx,123&lt;/div&gt;
&lt;div&gt;mov  ax,bx&lt;/div&gt;
&lt;div&gt;这至少要用到两条指令~~~要是mips机构的系统就好了，因为其中有&lt;/div&gt;
&lt;div&gt;3参数指令：&lt;/div&gt;
&lt;div&gt;addx   $1,$2,100     -----      $1=$2+100&lt;/div&gt;
&lt;div&gt;那么没办法了么？不是的！&lt;/div&gt;
&lt;div&gt;想一下 lea 指令 ,呵呵~~~看一下如下的指令：&lt;/div&gt;
&lt;div&gt;lea    ax,[bx+123]&lt;/div&gt;
&lt;div&gt;lea 取变量的偏移放入 ax 中，[] 代表变量是间接寻址，他的地址就等于[]&lt;/div&gt;
&lt;div&gt;中的值，即 bx+123,这样就达到了题目的目的。&lt;/div&gt;
&lt;div&gt;&lt;br&gt;3 用移位指令来代替乘法指令                   &lt;br&gt; &lt;/div&gt;
&lt;div&gt;大家都知道可以用移位指令来做形如 2,4,8 等2的整次幂的乘法，&lt;/div&gt;
&lt;div&gt;但是非整次幂呢？比如 乘10。其实很简单：&lt;/div&gt;
&lt;div&gt;36 * 10 = 36 * (8 + 2) = 36 * 8 + 36 * 2&lt;br&gt;即等于：&lt;br&gt;24h * 8 + 24h * 2 &lt;/div&gt;
&lt;div&gt;&lt;br&gt;接下来不用我讲了吧，这一方法也可以进一步推广。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;br&gt;4 察看 debug 状态寄存器 &lt;/div&gt;
&lt;div&gt; &lt;br&gt;  of（溢出）   df（方向）   if（中断）   sf（符号）   zf（零）   af（辅助进位）   pf（奇偶）   cf（进位）   &lt;br&gt;  为一的时候   &lt;br&gt;  ov(OVerflow)   dn(DowN)   ei(Enable   Interrupt)   ng(NeGtive)   zr(ZeRo)   ac(Auxiliary   Carry)   pe(Parity   Even)   cy(CarrY)   &lt;br&gt;  为零的时候   &lt;br&gt;  nv(Not   oVerflow)   up(UP)   di(DIsable   interrupt)   pl(PLus)   nz(Not   Zero)   na(Not   Auxiliary)   po(Parity   Odd)   nc(Not   Carry)   &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5 关于简单汇编环境的搭建&lt;/div&gt;
&lt;div&gt;如果是老鸟，则随心所欲自由选择。我在这里只是给新手一些我的建议。&lt;/div&gt;
&lt;div&gt;我一向反对新手一上来(毫无汇编编译经验)就使用汇编的集成开发环境比如&lt;/div&gt;
&lt;div&gt;radasm之类，这样不但容易出错，而且不能真正了解编译器和连接器的底&lt;/div&gt;
&lt;div&gt;层命令行用法。因为汇编本身编译就已经很简单了，不像C++之类有那么多&lt;/div&gt;
&lt;div&gt;优化的东东，你再套一个花里胡哨的集成环境，对初学者岂不很累？&lt;/div&gt;
&lt;div&gt;但我认为用一个带颜色标记的编辑器却是有必要的。&lt;/div&gt;
&lt;div&gt;(比如简单的几句用记事本就很好，复杂的我推荐使用editplus2(别忘了要&lt;/div&gt;
&lt;div&gt;下载汇编的语法文件。)&lt;/div&gt;
&lt;div&gt;&lt;br&gt;总的来说整个汇编环境是这样的:&lt;/div&gt;
&lt;div&gt;&lt;br&gt;16位dos程序: masm6.1x or nasm + editplus2&lt;/div&gt;
&lt;div&gt;32位windows程序: masm32v9.0 or nasm + editplus2 + 一个资源编辑器&lt;/div&gt;
&lt;div&gt;（masm611下载地址: &lt;a href="http://www.aogosoft.com"&gt;www.aogosoft.com&lt;/a&gt;，masm32下载地址 &lt;/div&gt;
&lt;div&gt;   &lt;a href="http://www.masm32.com"&gt;www.masm32.com&lt;/a&gt;)&lt;/div&gt;
&lt;div&gt;Trackback: &lt;a href="http://tb.blog.csdn.net/TrackBack.aspx?PostId=1776304"&gt;http://tb.blog.csdn.net/TrackBack.aspx?PostId=1776304&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;br&gt;附, 上述的第２点解决初学者常碰到的下述问题:&lt;br&gt;&lt;a href="http://topic.csdn.net/t/20051008/15/4312328.html"&gt;http://topic.csdn.net/t/20051008/15/4312328.html&lt;/a&gt;&lt;br&gt;上述也解决了这样一个问题:&lt;br&gt;楼主wjk302（影子传说）2005-10-08 15:17:37 在 其他开发语言 / 汇编语言 提问&lt;br&gt; lea指令在win32汇编中问题   &lt;br&gt;    &lt;br&gt;  ebp的值就是指向堆栈的地址对吧，那么lea   eax,[ebp]   &lt;br&gt;  就是得到ebp指向的堆栈内容的偏移地址，   &lt;br&gt;  和寄存器ebp的值是相同的么？   &lt;br&gt;  还有就是offset命令是相对于文件头的偏移地址，还是相对于整个寻址空间的偏移地址？   &lt;br&gt;1 楼mydo（侯佩|hopy|ks）回复于 2005-10-08 15:58:40 得分 5和寄存器ebp的值是相同的么？   &lt;br&gt;  yes!&lt;br&gt;Top&lt;/div&gt;
&lt;div&gt;2 楼wjk302（影子传说）回复于 2005-10-08 16:09:46 得分 0 1.如果和和寄存器ebp的值是相同的，那么   lea   eax,[ebp]   等价于   mov   eax,ebp   ？？？   &lt;br&gt;  2.offset命令是相对于文件头的偏移地址，还是相对于整个寻址空间的偏移地址？？？&lt;br&gt;Top&lt;/div&gt;
&lt;div&gt;3 楼csdsjkk（）回复于 2005-10-08 16:57:30 得分 5cpu   中没有文件的概念，当然是指地址空间了   &lt;br&gt;    &lt;br&gt;  &lt;br&gt;Top&lt;/div&gt;
&lt;div&gt;4 楼wjk302（影子传说）回复于 2005-10-08 17:07:04 得分 0 最后一点了   1.如果和和寄存器ebp的值是相同的，那么   lea   eax,[ebp]   等价于   mov   eax,ebp   ？？？   &lt;br&gt;  &lt;br&gt;Top&lt;/div&gt;
&lt;div&gt;5 楼mydo（侯佩|hopy|ks）回复于 2005-10-08 17:21:24 得分 10请到我的blog参考     &amp;quot;看似   &amp;quot;不可能&amp;quot;   的汇编问题&amp;quot;   一章:   &lt;br&gt;    &lt;br&gt;  &lt;a href="http://hopy.blogchina.com/"&gt;http://hopy.blogchina.com/&lt;/a&gt;&lt;br&gt;&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+%e6%b1%87%e7%bc%96%e5%88%9d%e5%ad%a6%e8%80%85%e9%97%ae%e9%a2%98%e5%90%88%e9%9b%86(%e8%bd%ac)&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1033.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1033.entry</guid><pubDate>Wed, 24 Oct 2007 02:01:08 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1033/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1033.entry#comment</wfw:comment><dcterms:modified>2007-10-24T02:01:08Z</dcterms:modified></item><item><title>在vc中调试汇编程序</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1031.entry</link><description>&lt;p&gt;在vc中调试汇编程序: 
&lt;p&gt;实现方法参见转来的几篇文章: 
&lt;p&gt;1. 贴个用VC++在源码级下调试MASM32汇编程序的方法。。。大家交流。。 (转)&lt;br&gt;摘自: &lt;a href="http://www.pediy.com/bbshtml/bbs5/pediy50355.htm"&gt;http://www.pediy.com/bbshtml/bbs5/pediy50355.htm&lt;/a&gt;&lt;br&gt;标 题:贴个用VC++在源码级下调试MASM32汇编程序的方法。。。大家交流。。 (1千字)&lt;br&gt;发信人:Spring.W&lt;br&gt;时 间:2002-11-25 0:27:11&lt;br&gt;详细信息: 
&lt;p&gt;&lt;br&gt;许多其它编译器都附带了源代码级的调试器,,这使得用这些高级语言调试比较简单,但对于masm并没有一个集成的开发和调试环境,我们可以用TRW和Softice实现源码级的调试，这两种方法，参看Hume兄的文章：&lt;a href="http://www.finalseraph.org/hume/asmdata/sdbg.htm"&gt;http://www.finalseraph.org/hume/asmdata/sdbg.htm&lt;/a&gt; 
&lt;p&gt;下面提供一种用VC++6.0调试的方法，好像比前两种更简单些。 
&lt;p&gt;方法如下： &lt;br&gt;-------- &lt;br&gt;1、将我们的汇编程序编译连接成调试模式： &lt;br&gt;  \masm32\bin\ml /c /coff /Cp /Zi Myprog.asm &lt;br&gt;  \masm32\bin\link /DEBUG /DEBUGTYPE:CV /subsystem:windows  &lt;br&gt;  myProg.obj &lt;br&gt;2、用VC++6.0建立一个同ASM程序同名字的工程：myProg，并将它编译连接 &lt;br&gt;  成debug模式，此时，在VC工程myProg\debug中会形成myProg.exe。 &lt;br&gt;3、将第1步骤中用Masm32编译连接成的同名exe文件myProg.exe拷贝到： &lt;br&gt;  VC++工程myProg\debug中，覆盖VC++形成myProg.exe &lt;br&gt;4、启动VC++6.0，打开myProg工程，build-&amp;gt;start debug-&amp;gt;go，呵呵。。 &lt;br&gt;  进入了Masm32形成的myProg.exe，并且是源码级调试。 
&lt;p&gt;  至此，请随心所欲的用VC调试器的强大功能，调试你的Masm32程序吧！ 
&lt;p&gt;附：我一般都是用个批处理(L_debug.bat)一下完成： &lt;br&gt;c:\masm32\bin\ml /c /coff /Cp /Zi Myprog.asm &amp;gt;Mydebug.txt &lt;br&gt;c:\masm32bin\link /DEBUG /DEBUGTYPE:CV /subsystem:windows &lt;br&gt;  myProg.obj &lt;br&gt;  copy .\myProg.exe VC工程\debug\myProg.exe &lt;br&gt;启动VC进行调试。。。 
&lt;p&gt;                                        Spring.W &lt;br&gt;                                        2002/11/25 
&lt;p&gt; 
&lt;p&gt;2. 标 题: Myshell.asm的错误更正及在VC中融合masm32编译的方法&lt;br&gt;作 者: Spring.W&lt;br&gt;时 间: 2005-03-14,23:24&lt;br&gt;链 接: &lt;a href="http://bbs.pediy.com/showthread.php?t=12067"&gt;http://bbs.pediy.com/showthread.php?t=12067&lt;/a&gt;
&lt;p&gt;有朋友来信说：Myshell.asm用TestVC测试时候，报告找不到文件，出错原因如下：
&lt;p&gt;;----------------------------------------------&lt;br&gt;WJQ_PUSHA  MACRO&lt;br&gt;    push  ebx&lt;br&gt;    push  ecx&lt;br&gt;    push  edx&lt;br&gt;    push  esi&lt;br&gt;    push  edi&lt;br&gt;    push  ebp&lt;br&gt;    pushfd        ;;;这里原来是pushf,是16为的标志入栈，产生了错误&lt;br&gt;      ENDM&lt;br&gt;;----------------------------------------------&lt;br&gt;WJQ_POPA  MACRO&lt;br&gt;    popfd        ;;;这里原来是popf,是16为的标志出栈，产生了错误&lt;br&gt;    pop    ebp&lt;br&gt;    pop    edi&lt;br&gt;    pop    esi&lt;br&gt;    pop    edx&lt;br&gt;    pop    ecx&lt;br&gt;    pop    ebx&lt;br&gt;      ENDM&lt;br&gt;;----------------------------------------------
&lt;p&gt;在此对各位朋友深表歉意！
&lt;p&gt;另外：&lt;br&gt;    介绍一种VC工程直接融合了MASM32汇编编译的方法：&lt;br&gt;    这样可以直接在这个工程中对myshell.asm进行编译了连接了，而且也可以直接追踪到myshell.asm的源码中了。
&lt;p&gt;方法如下：&lt;br&gt;1、将myshell.asm填加到VC工程的Source files中；&lt;br&gt;2、将Source files中的myshell.obj删除；&lt;br&gt;3、在Source files中的myshell.asm上：右键-&amp;gt;Setting-&amp;gt;选中Custom Build页&lt;br&gt;   在Commands中输入：&lt;br&gt;   如果是DEBUG模式，则输入： &lt;br&gt;   c:\masm32\bin\ml /c /coff /Zi /FoDEBUG\$(InputName).obj $(InputPath) 
&lt;p&gt;   如果是RELEASE模式，则输入： &lt;br&gt;   c:\masm32\bin\ml /c /coff /FoRELEASE\$(InputName).obj $(InputPath)
&lt;p&gt;   在Outputs中输入：&lt;br&gt;   如果是DEBUG模式，则输入： &lt;br&gt;   DEBUG\$(InputName).obj
&lt;p&gt;   如果是RELEASE模式，则输入： &lt;br&gt;   RELEASE\$(InputName).obj
&lt;p&gt;   如果您的没有把masm安装在c盘，则要作相应的修改。
&lt;p&gt;之后，您可以直接对TestVC工程编译连接了。&lt;br&gt;------------------------------------------------------------------------
&lt;p&gt;   再次谢谢各位朋友的来信！&lt;br&gt;      &lt;br&gt;                                 Spring.W&lt;br&gt;                                 2005.3.15 &lt;br&gt;
&lt;p&gt;3. 使用VC6调试器源码级调试win32汇编程序(转)&lt;br&gt;摘自: &lt;a href="http://blog.csdn.net/hejiwen2001/archive/2005/06/16/395823.aspx"&gt;http://blog.csdn.net/hejiwen2001/archive/2005/06/16/395823.aspx&lt;/a&gt;     &lt;br&gt;                                                                                                  &lt;br&gt;作者：溟初&lt;br&gt;       本人拙笨，如有错误请批评指正，如有更好的方法或者技巧，欢迎互相交流。&lt;a href="mailto:hejiwen2001@sohu.com"&gt;hejiwen2001@sohu.com&lt;/a&gt;.。&lt;br&gt;       &lt;br&gt;       使用一个好的调试器无疑对学习win32汇编是至关重要的，本人更偏爱VC的强大调试环境，能否用VC调试器调试哪，于是从网上搜搜，找到一篇Spring.W的文章《贴个用VC++在源码级下调试MASM32汇编程序的方法。。。大家交流。。》，此文就是在此基础上的扩充。&lt;br&gt; &lt;br&gt;编程环境：VC6.0，Masm32v8&lt;br&gt; &lt;br&gt;方法如下：&lt;br&gt;1、  使用VC6新建一个空工程test（win32 console，win32 application等均可）。&lt;br&gt;2、  把汇编工程中的文件拷至新建工程目录下（hello.asm，makefile），并把这些文件加入工程中管理。&lt;br&gt;3、  配置IDE：&lt;br&gt;（1）、tools/customize…/tools中添加一个工具nmake。在menu contens中添加一项nmake，Command中填入：nmake.exe，Initial Directory中填入： $(WkspDir)，选中use output window。这样就在tools菜单下出现了一个新的菜单项nmake。可以把这个菜单项添加到工具栏中。&lt;br&gt;（2）、tools/option…/editor在save option中选中save befor running tools。&lt;br&gt;4、   制作makefile文件：&lt;br&gt; &lt;br&gt;EXE = test.exe                    #指定输出文件&lt;br&gt;OBJS = hello.obj                 #需要的目标文件&lt;br&gt; &lt;br&gt;LINK_FLAG = /subsystem:windows /DEBUG /OUT:debug\test.exe   #连接选项        &lt;br&gt;#注： （1）/DEBUG必须存在 。&lt;br&gt;#         （2）/OUT:debug\test.exe输出可执行文件名要与VC建立的工程名一致。&lt;br&gt;#         （3）/subsystem:windows：如果是控制台程序，这里需要改为/subsystem:console&lt;br&gt; &lt;br&gt;ML_FLAG = /c /coff /Zi                #编译选项         &lt;br&gt;#注： /Zi必须存在&lt;br&gt; &lt;br&gt;$(EXE): $(OBJS)&lt;br&gt;                  Link $(LINK_FLAG) $(OBJS)&lt;br&gt;.asm.obj:&lt;br&gt;         ml $(ML_FLAG) $&amp;lt;&lt;br&gt;5、点击菜单项tools/nmake，调用masm32中的ml，link进行编译连接程序。&lt;br&gt; &lt;br&gt;至此就可以使用VC调试器源码级调试汇编程序了，可以设置断点，察看变量、内存、寄存器等，nmake出现语法错误时可以双击output window中的错误行定位到程序中的指定行，改代码时别忘了要用nmake编译。&lt;br&gt;注：变量最好不要以@开头定义，比如@num，这样的变量名无法再vc下察看。&lt;br&gt; &lt;br&gt;参考：&lt;br&gt;&lt;a href="http://www.pediy.com/bbshtml/bbs5/pediy50355.htm"&gt;http://www.pediy.com/bbshtml/bbs5/pediy50355.htm&lt;/a&gt;  作者：Spring.W&lt;br&gt;&lt;a href="http://bbs.pediy.com/showthread.php?s=16dcabc8aa048f28da0e3d5b68712147&amp;amp;threadid=12067"&gt;http://bbs.pediy.com/showthread.php?s=16dcabc8aa048f28da0e3d5b68712147&amp;amp;threadid=12067&lt;/a&gt; 作者：Spring.W&lt;br&gt;&lt;a href="http://www.aogosoft.com/bbs/mixpage.asp?mode=viewoktext&amp;amp;fileid=123"&gt;http://www.aogosoft.com/bbs/mixpage.asp?mode=viewoktext&amp;amp;fileid=123&lt;/a&gt; 作者：crige&lt;br&gt;&lt;a href="http://asm.yeah.net/"&gt;http://asm.yeah.net&lt;/a&gt; 《Windows环境下32位汇编语言程序设计》pdf及代码 作者：罗云彬&lt;br&gt;附件：代码及配置图片(下载&lt;a href="http://bbs.pediy.com/showthread.php?s=&amp;amp;threadid=14196"&gt;http://bbs.pediy.com/showthread.php?s=&amp;amp;threadid=14196&lt;/a&gt;)。&lt;br&gt;                                                                                                                                                                        2005/6/2 
&lt;p&gt;  
&lt;p&gt;Trackback: &lt;a href="http://tb.blog.csdn.net/TrackBack.aspx?PostId=395823"&gt;http://tb.blog.csdn.net/TrackBack.aspx?PostId=395823&lt;/a&gt; 
&lt;p&gt; &lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+%e5%9c%a8vc%e4%b8%ad%e8%b0%83%e8%af%95%e6%b1%87%e7%bc%96%e7%a8%8b%e5%ba%8f&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1031.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1031.entry</guid><pubDate>Tue, 23 Oct 2007 07:06:16 GMT</pubDate><slash:comments>1</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1031/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1031.entry#comment</wfw:comment><dcterms:modified>2007-10-23T07:34:18Z</dcterms:modified></item><item><title>0xC0000006: In page error这样的错误</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1030.entry</link><description>&lt;p&gt;最近好些玩家的机器碰到0xC0000006: In page error这样的错误&lt;br&gt;我想知道这种错误有没有可能是我们程序bug造成的，还是系统查找页表出的问题. 
&lt;p&gt;如何解决.&lt;br&gt;（如果您知道请留言，或是发email告诉我&lt;a href="mailto:flipcode@msn.com"&gt;flipcode@msn.com&lt;/a&gt;，非常感谢!） 
&lt;p&gt;注:该问题已解决. 方法是采用了ryan的提议:自己读取贴图文件再用d3d的内存创建贴图.
&lt;p&gt;这样经验证再没收到用户返回 的此类crash
&lt;p&gt;&lt;br&gt;flywind 13:41:30&lt;br&gt;关于MPRender::LoadTexture这个bug一直没能解决，&lt;br&gt;只知道是0xC0000006: In page error这样的错误,&lt;br&gt;crash在d3d的函数中(D3DXCreateTextureFromFileEx) 
&lt;p&gt;flywind 13:43:31&lt;br&gt;查看到一些别人的程序也碰到这样的crash，但未见真正解决方案....:&lt;br&gt;1. KiXtart&lt;br&gt;&lt;a href="http://listes2.ac-nancy-metz.fr/wws/d_read/kheops/kixtart/Kix95.doc"&gt;http://listes2.ac-nancy-metz.fr/wws/d_read/kheops/kixtart/Kix95.doc&lt;/a&gt;&lt;br&gt;Make sure that you do not, in any way, disconnect or re-redirect the drive from which KIX32.EXE was started. Also, these faults can be caused by antivirus software. If you use antivirus software, make sure you are using the latest version and if the problem persists, test if disabling the antivirus software solves the problem.&lt;br&gt;flywind 13:44:10 
&lt;p&gt;2. wow的:&lt;br&gt;&lt;a href="http://www.viker.org/bbs/39141-post1.html"&gt;http://www.viker.org/bbs/39141-post1.html&lt;/a&gt;&lt;br&gt;我的WOW最近老是出现问题,重新装了也没用,你们看下,谁知道怎么解决的跟...&lt;br&gt;This application has encountered a critical error:&lt;br&gt;ERROR #132 (0x85100084) Fatal Exception&lt;br&gt;Program: E:\World of Warcraft\WoW.exe&lt;br&gt;Exception: 0xC0000006 (IN_PAGE_ERROR) at 001B:00656FFC 
&lt;p&gt;flywind 13:44:51&lt;br&gt;3. office 2003的:&lt;br&gt;  &lt;a href="http://support.microsoft.com/kb/833267"&gt;http://support.microsoft.com/kb/833267&lt;/a&gt;&lt;br&gt;症状&lt;br&gt;当您尝试设置或修复 Microsoft Office 2003 或 Microsoft Office XP 安装时，安装设置或修复可能会意外退出，并且不显示错误信息。 
&lt;p&gt;如果您检查安装日志文件，可能会看到与下列其中一项类似的项：&lt;br&gt;Exception code:C0000006 IN_PAGE_ERROR Module:C:\WINDOWS\System32\msi.dll Function:0x7642452f&lt;br&gt;Exception code:C0000006 IN_PAGE_ERROR Module:C:\WINDOWS\system32\IMAGEHLP.dll Function:0x76c94afa&lt;br&gt;注意：模块和函数可能不同。&lt;br&gt;回到顶端 
&lt;p&gt;原因&lt;br&gt;当您的操作系统已损坏时，或者您的硬盘驱动器有问题时，可能会发生此问题。 
&lt;p&gt;flywind 13:46:36&lt;br&gt;4. xHarbour 的:&lt;br&gt;&lt;a href="http://delphi.newswhat.com/geoxml/forumhistorythread?groupname=Advantage.Clipper&amp;amp;messageid=3f1cedfd@solutions.advantagedatabase.com"&gt;http://delphi.newswhat.com/geoxml/forumhistorythread?groupname=Advantage.Clipper&amp;amp;messageid=3f1cedfd@solutions.advantagedatabase.com&lt;/a&gt;&lt;br&gt;这个好象是在说同一个文件在网络共享使用时，可能会发生 
&lt;p&gt;张 13:47:14&lt;br&gt;说的都是页面访问错误 
&lt;p&gt;张 13:47:32&lt;br&gt;好像跟D3DXCreateTextureFromFileEx没有联系。 
&lt;p&gt;flywind 13:47:34&lt;br&gt;是的，第４个说的比较仔细 
&lt;p&gt;flywind 13:47:47&lt;br&gt;还举了一个例子 
&lt;p&gt;flywind 13:49:18&lt;br&gt;5. Eudora non responding &lt;br&gt;&lt;a href="http://eudorabb.qualcomm.com/showthread.php?t=3046"&gt;http://eudorabb.qualcomm.com/showthread.php?t=3046&lt;/a&gt;&lt;br&gt;Hey 
&lt;p&gt;After recieving some email messages, I go to open one and the message window is opened and the message is displayed. But then I get a error message saying an &amp;quot;Unhandled exeption has occured&amp;quot; and Eudora just hangs until I go into Windows Task Manager and end the task. 
&lt;p&gt;I opened up the exception log and got the following&lt;br&gt;------------------------------------------------------------------------&lt;br&gt;Exception code: c0000006 IN_PAGE_ERROR&lt;br&gt;Fault address: 7722790b 01:0007690b C:\WINDOWS\system32\WININET.dll 
&lt;p&gt;flywind 13:50:04&lt;br&gt;这个好象是说他打开时，别人正在用任务管理器结束了？ 
&lt;p&gt;张 13:51:04&lt;br&gt;如果指针的值被错误的修改成进程用户地址范围以外的值（比如c0000006），都会出现访问违规的吧 
&lt;p&gt;flywind 13:51:22&lt;br&gt;违规访问，以前有，不是提示这个的 
&lt;p&gt;flywind 13:51:27&lt;br&gt;是访问非法 
&lt;p&gt;张 13:52:12&lt;br&gt;读取和写入都是一样的提示么？ 
&lt;p&gt;flywind 13:52:23&lt;br&gt;是的 
&lt;p&gt;flywind 13:52:35&lt;br&gt;后面提示不一样，前面是一样的 
&lt;p&gt;flywind 13:53:29&lt;br&gt;是类似于这样的:&lt;br&gt;0xC0000005: Access violation writing location 0x101b88cc. 
&lt;p&gt;flywind 13:53:59&lt;br&gt;上面是写，&lt;br&gt;下面是读:&lt;br&gt;0xC0000005: Access violation reading location 0x000500b4. 
&lt;p&gt;flywind 13:55:15&lt;br&gt;0xC0000005 是访问非法的error code&lt;br&gt;0xc0000006 是分页/IO访问错误 
&lt;p&gt;&lt;br&gt;张 14:02:51&lt;br&gt;访问一个内存地址，系统查找页表，如果对应得表项没有映射到内存或磁盘，可能就会出现这种错误。&lt;br&gt;flywind 14:08:32&lt;br&gt;嗯，前面一些文章说的是这样意思 
&lt;div&gt;&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+0xC0000006%3a+In+page+error%e8%bf%99%e6%a0%b7%e7%9a%84%e9%94%99%e8%af%af&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1030.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1030.entry</guid><pubDate>Tue, 23 Oct 2007 06:09:49 GMT</pubDate><slash:comments>1</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1030/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1030.entry#comment</wfw:comment><dcterms:modified>2008-01-03T01:31:12Z</dcterms:modified></item><item><title>编译lua5.1debug版本</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1028.entry</link><description>&lt;p&gt;编译lua5.1debug版本
&lt;p&gt;---- &lt;a href="mailto:flipcode@msn.com"&gt;flipcode@msn.com&lt;/a&gt;
&lt;div&gt;按win+R输入cmd运行控制台&lt;/div&gt;
&lt;p&gt;1. 先运行设置vc的环境设置:
&lt;p&gt;E:\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat
&lt;p&gt;2. 在lua-5.1目录下的etc找到luavc.bat, 执行即可.
&lt;p&gt;另外如果需要编译debug版，可将luavc.bat修改如下再运行即可:
&lt;p&gt;cd src&lt;br&gt;cl /Od /W3 /c /Zi /D &amp;quot;LUA_BUILD_AS_DLL&amp;quot; l*.c&lt;br&gt;del lua.obj luac.obj&lt;br&gt;link /LDd /DEBUG /PDB:&amp;quot;lua51d.pdb&amp;quot; /DLL /out:lua51d.dll l*.obj
&lt;p&gt;cl /Od /W3 /c /Zi /D &amp;quot;LUA_BUILD_AS_DLL&amp;quot; lua.c&lt;br&gt;link /LDd /DEBUG /PDB:&amp;quot;luad.pdb&amp;quot; /out:luad.exe lua.obj lua51d.lib&lt;br&gt;cd ..
&lt;p&gt;&lt;br&gt;附vc命令行参数意义如下:
&lt;p&gt;优化-  &lt;br&gt;/O1 最小化空间 minimize space&lt;br&gt;/Op[-] 改善浮点数一致性 improve floating-pt consistency&lt;br&gt;/O2 最大化速度 maximize speed&lt;br&gt;/Os  优选代码空间  favor code space&lt;br&gt;/Oa 假设没有别名 assume no aliasing&lt;br&gt;/Ot 优选代码速度 favor code speed&lt;br&gt;/Ob 内联展开（默认 n=0） inline expansion (default n=0)&lt;br&gt;/Ow  假设交叉函数别名  assume cross-function aliasing&lt;br&gt;/Od  禁用优化（默认值）  disable optimizations (default)&lt;br&gt;/Ox  最大化选项。(/Ogityb2 /Gs) maximum opts. (/Ogityb1 /Gs)&lt;br&gt;/Og  启用全局优化  enable global optimization  &lt;br&gt;/Oy[-]  启用框架指针省略  enable frame pointer omission&lt;br&gt;/Oi  启用内建函数  enable intrinsic functions
&lt;p&gt;&lt;br&gt;-代码生成-  &lt;br&gt;/G3  为 80386 进行优化  optimize for 80386&lt;br&gt;/G4  为 80486 进行优化  optimize for 80486&lt;br&gt;/GR[-]  启用 C++ RTTI  enable C++ RTTI&lt;br&gt;/G5  为 Pentium 进行优化  optimize for Pentium&lt;br&gt;/G6 为 Pentium Pro 进行优化  optimize for Pentium Pro&lt;br&gt;/GX[-]  启用 C++ 异常处理（与 /EHsc 相同）  enable C++ EH (same as /EHsc)&lt;br&gt;/EHs  启用同步 C++ 异常处理  enable synchronous C++ EH&lt;br&gt;/GD 为 Windows DLL 进行优化 optimize for Windows DLL&lt;br&gt;/GB  为混合模型进行优化（默认）  optimize for blended model (default)&lt;br&gt;/EHa  启用异步 C++ 异常处理  enable asynchronous C++ EH&lt;br&gt;/Gd  __cdecl 调用约定  __cdecl calling convention  &lt;br&gt;/EHc  extern“C”默认为 nothrow  extern &amp;quot;C&amp;quot; defaults to nothrow&lt;br&gt;/Gr  __fastcall 调用约定  __fastcall calling convention&lt;br&gt;/Gi[-] 启用增量编译 enable incremental compilation&lt;br&gt;/Gz  __stdcall 调用约定  __stdcall calling convention  &lt;br&gt;/Gm[-]  启用最小重新生成  enable minimal rebuild&lt;br&gt;/GA  为 Windows 应用程序进行优化 optimize for Windows Application&lt;br&gt;/Gf  启用字符串池  enable string pooling  &lt;br&gt;/QIfdiv[-]  启用 Pentium FDIV 修复  enable Pentium FDIV fix  &lt;br&gt;/GF  启用只读字符串池  enable read-only string pooling  &lt;br&gt;/QI0f[-]  启用 Pentium 0x0f 修复  enable Pentium 0x0f fix&lt;br&gt;/Gy  分隔链接器函数  separate functions for linker&lt;br&gt;/GZ  启用运行时调试检查 enable runtime debug checks&lt;br&gt;/Gh 启用钩子函数调用 enable hook function call&lt;br&gt;/Ge  对所有函数强制堆栈检查  force stack checking for all funcs&lt;br&gt;/Gs[num]  禁用堆栈检查调用  disable stack checking calls
&lt;p&gt;&lt;br&gt;-输出文件-  &lt;br&gt;/Fa[file]  命名程序集列表文件  name assembly listing file&lt;br&gt;/Fo  命名对象文件  name object file&lt;br&gt;/FA[sc]  配置程序集列表  configure assembly listing  &lt;br&gt;/Fp  命名预编译头文件  name precompiled header file&lt;br&gt;/Fd[file]  命名 .PDB 文件  name .PDB file  &lt;br&gt;/Fr[file]  命名源浏览器文件  name source browser file&lt;br&gt;/Fe  命名可执行文件  name executable file&lt;br&gt;/FR[file]  命名扩展 .SBR 文件  name extended .SBR file&lt;br&gt;/Fm[file]  命名映射文件  name map file
&lt;p&gt;&lt;br&gt;-预处理器-  &lt;br&gt;/FI  命名强制包含文件  name forced include file&lt;br&gt;/C  不吸取注释  don't strip comments  &lt;br&gt;/U  移除预定义宏  remove predefined macro&lt;br&gt;/D{=|#}  定义宏  define macro&lt;br&gt;/u  移除所有预定义宏  remove all predefined macros&lt;br&gt;/E  将预处理定向到标准输出 preprocess to stdout&lt;br&gt;/I 添加到包含文件的搜索路径  add to include search path&lt;br&gt;/EP  将预处理定向到标准输出，不要带行号  preprocess to stdout, no #line&lt;br&gt;/X  忽略“标准位置”  ignore &amp;quot;standard places&amp;quot;&lt;br&gt;/P  预处理到文件  preprocess to file
&lt;p&gt;&lt;br&gt;-语言-  &lt;br&gt;/Zi  启用调试信息  enable debugging information&lt;br&gt;/Zl  忽略 .OBJ 中的默认库名  omit default library name in .OBJ&lt;br&gt;/ZI  启用调试信息的“编辑并继续”功能 enable Edit and Continue debug info&lt;br&gt;/Zg  生成函数原型  generate function prototypes&lt;br&gt;/Z7  启用旧式调试信息  enable old-style debug info&lt;br&gt;/Zs  只进行语法检查  syntax check only&lt;br&gt;/Zd  仅要行号调试信息  line number debugging info only&lt;br&gt;/vd{0|1}  禁用/启用 vtordisp  disable/enable vtordisp&lt;br&gt;/Zp[n]  在 n 字节边界上包装结构  pack structs on n-byte boundary&lt;br&gt;/vm  指向成员的指针类型  type of pointers to members&lt;br&gt;/Za  禁用扩展（暗指 /Op）  disable extensions (implies /Op)&lt;br&gt;/noBool  禁用“bool”关键字  disable &amp;quot;bool&amp;quot; keyword&lt;br&gt;/Ze  启用扩展（默认）  enable extensions (default)
&lt;p&gt;&lt;br&gt;- 杂项 -  &lt;br&gt;/?, /help  打印此帮助消息  print this help message&lt;br&gt;/c  只编译，不链接  compile only, no link&lt;br&gt;/W  设置警告等级（默认 n=1）  set warning level (default n=1)&lt;br&gt;/H  最大化外部名称长度  max external name length&lt;br&gt;/J  默认 char 类型是 unsigned  default char type is unsigned&lt;br&gt;/nologo  取消显示版权消息  suppress copyright message&lt;br&gt;/WX  将警告视为错误  treat warnings as errors&lt;br&gt;/Tc  将文件编译为 .c  compile file as .c  &lt;br&gt;/Yc[file]  创建 .PCH 文件  create .PCH file&lt;br&gt;/Tp  将文件编译为 .cpp  compile file as .cpp  &lt;br&gt;/Yd  将调试信息放在每个 .OBJ 中  put debug info in every .OBJ&lt;br&gt;/TC  将所有文件编译为 .c  compile all files as .c  &lt;br&gt;/TP  将所有文件编译为 .cpp  compile all files as .cpp  &lt;br&gt;/Yu[file]  使用 .PCH 文件  use .PCH file&lt;br&gt;/V  设置版本字符串  set version string&lt;br&gt;/YX[file]  自动的 .PCH 文件 automatic .PCH&lt;br&gt;/w  禁用所有警告  disable all warnings&lt;br&gt;/Zm  最大内存分配（默认为 %）  max memory alloc (% of default)
&lt;p&gt;&lt;br&gt;-链接-  &lt;br&gt;/MD  与 MSVCRT.LIB 链接  link with MSVCRT.LIB&lt;br&gt;/MDd  与 MSVCRTD.LIB 调试库链接  link with MSVCRTD.LIB debug lib&lt;br&gt;/ML  与 LIBC.LIB 链接  link with LIBC.LIB&lt;br&gt;/MLd  与 LIBCD.LIB 调试库链接  link with LIBCD.LIB debug lib&lt;br&gt;/MT  与 LIBCMT.LIB 链接  link with LIBCMT.LIB  &lt;br&gt;/MTd  与 LIBCMTD.LIB 调试库链接  link with LIBCMTD.LIB debug lib&lt;br&gt;/LD  创建 .DLL  Create .DLL  &lt;br&gt;/F  设置堆栈大小  set stack size&lt;br&gt;/LDd  创建 .DLL 调试库  Create .DLL debug libary&lt;br&gt;/link  [链接器选项和库]  [linker options and libraries]&lt;br&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+%e7%bc%96%e8%af%91lua5.1debug%e7%89%88%e6%9c%ac&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1028.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1028.entry</guid><pubDate>Thu, 18 Oct 2007 01:37:39 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1028/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1028.entry#comment</wfw:comment><dcterms:modified>2007-10-18T01:37:39Z</dcterms:modified></item><item><title>dx 程序crash问题</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1026.entry</link><description>&lt;div&gt;war3在运行时立即按下win+L键，然后再登录回到windows继续时会crash!&lt;br&gt;&lt;br&gt;directx sdk提供的程序也会!&lt;br&gt;　&lt;br&gt;我们的程序也一样.　　&lt;br&gt;&lt;br&gt;结论：　估计XP下(其它系统未知)dx程序都会有这种情况...&lt;br&gt;&lt;br&gt;我想知道碰到这种情况，有没有办法解决! &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+dx+%e7%a8%8b%e5%ba%8fcrash%e9%97%ae%e9%a2%98&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1026.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1026.entry</guid><pubDate>Fri, 12 Oct 2007 07:41:00 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1026/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1026.entry#comment</wfw:comment><dcterms:modified>2007-10-12T07:41:00Z</dcterms:modified></item><item><title>OGRE的分辨率枚举类不错啊</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1025.entry</link><description>&lt;div&gt;dx9的分辨率枚举总感觉有点点麻烦，我原来还用了ddraw来枚举，&lt;/div&gt;
&lt;div&gt;参考了一下OGRE3D,发现原来是很轻松的事,　现在也改到dx9来枚举分辨率了 &lt;img title="大笑" style="vertical-align:middle" height=19 alt="大笑" src="http://shared.live.com/TbRB5QUAj!9gMQWPUATZLg/emoticons/smile_teeth.gif" width=19&gt;&lt;/div&gt;
&lt;div&gt;但是还是有个令人不太满意的地方: 见上一篇文章显存获取.&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+OGRE%e7%9a%84%e5%88%86%e8%be%a8%e7%8e%87%e6%9e%9a%e4%b8%be%e7%b1%bb%e4%b8%8d%e9%94%99%e5%95%8a&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1025.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1025.entry</guid><pubDate>Fri, 12 Oct 2007 07:39:00 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1025/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1025.entry#comment</wfw:comment><dcterms:modified>2007-10-12T07:39:00Z</dcterms:modified></item><item><title>IBM Rational PurifyPlus</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1024.entry</link><description>&lt;div&gt;IBM Rational PurifyPlus 是个好东西，网上居然找到破解码&lt;img title="大笑" style="vertical-align:middle" alt="大笑" src="http://shared.live.com/TbRB5QUAj!9gMQWPUATZLg/emoticons/smile_teeth.gif"&gt;, 不要问我要，我用正版哈&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+IBM+Rational+PurifyPlus&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1024.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1024.entry</guid><pubDate>Fri, 12 Oct 2007 07:34:08 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1024/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1024.entry#comment</wfw:comment><dcterms:modified>2007-10-12T07:34:08Z</dcterms:modified></item><item><title>使用Visual Leak Detector检测内存泄漏 (转)</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1020.entry</link><description>&lt;div&gt;使用Visual Leak Detector检测内存泄漏 (转)&lt;br&gt;摘自: &lt;a href="http://www.testage.net/AutoTest/Opentest/200609/896.htm"&gt;http://www.testage.net/AutoTest/Opentest/200609/896.htm&lt;/a&gt;&lt;br&gt; &lt;br&gt;作者：dofty    文章来源：dofty的专栏    点击数：    更新时间：2006-9-8     &lt;br&gt; &lt;br&gt;初识Visual Leak Detector&lt;br&gt;       灵活自由是C/C++语言的一大特色，而这也为C/C++程序员出了一个难题。当程序越来越复杂时，内存的管理也会变得越加复杂，稍有不慎就会出现内存问题。内存泄漏是最常见的内存问题之一。内存泄漏如果不是很严重，在短时间内对程序不会有太大的影响，这也使得内存泄漏问题有很强的隐蔽性，不容易被发现。然而不管内存泄漏多么轻微，当程序长时间运行时，其破坏力是惊人的，从性能下降到内存耗尽，甚至会影响到其他程序的正常运行。另外内存问题的一个共同特点是，内存问题本身并不会有很明显的现象，当有异常现象出现时已时过境迁，其现场已非出现问题时的现场了，这给调试内存问题带来了很大的难度。&lt;/div&gt;
&lt;div&gt;       &lt;/div&gt;
&lt;div&gt;       Visual Leak Detector是一款用于Visual C++的免费的内存泄露检测工具。可以在&lt;a href="http://www.codeproject.com/tools/visualleakdetector.asp"&gt;http://www.codeproject.com/tools/visualleakdetector.asp&lt;/a&gt; 下载到。相比较其它的内存泄露检测工具，它在检测到内存泄漏的同时，还具有如下特点：&lt;/div&gt;
&lt;div&gt;1、  可以得到内存泄漏点的调用堆栈，如果可以的话，还可以得到其所在文件及行号；&lt;/div&gt;
&lt;div&gt;2、  可以得到泄露内存的完整数据；&lt;/div&gt;
&lt;div&gt;3、  可以设置内存泄露报告的级别；&lt;/div&gt;
&lt;div&gt;4、  它是一个已经打包的lib，使用时无须编译它的源代码。而对于使用者自己的代码，也只需要做很小的改动；&lt;/div&gt;
&lt;div&gt;5、  他的源代码使用GNU许可发布，并有详尽的文档及注释。对于想深入了解堆内存管理的读者，是一个不错的选择。&lt;/div&gt;
&lt;div&gt;       &lt;/div&gt;
&lt;div&gt;       可见，从使用角度来讲，Visual Leak Detector简单易用，对于使用者自己的代码，唯一的修改是#include Visual Leak Detector的头文件后正常运行自己的程序，就可以发现内存问题。从研究的角度来讲，如果深入Visual Leak Detector源代码，可以学习到堆内存分配与释放的原理、内存泄漏检测的原理及内存操作的常用技巧等。&lt;/div&gt;
&lt;div&gt;       本文首先将介绍Visual Leak Detector的使用方法与步骤，然后再和读者一起初步的研究Visual Leak Detector的源代码，去了解Visual Leak Detector的工作原理。&lt;/div&gt;
&lt;div&gt;&lt;br&gt;使用Visual Leak Detector(1.0)&lt;br&gt;       下面让我们来介绍如何使用这个小巧的工具。&lt;/div&gt;
&lt;div&gt;       首先从网站上下载zip包，解压之后得到vld.h, vldapi.h, vld.lib, vldmt.lib, vldmtdll.lib, dbghelp.dll等文件。将.h文件拷贝到Visual C++的默认include目录下，将.lib文件拷贝到Visual C++的默认lib目录下，便安装完成了。因为版本问题，如果使用windows 2000或者以前的版本，需要将dbghelp.dll拷贝到你的程序的运行目录下，或其他可以引用到的目录。&lt;/div&gt;
&lt;div&gt;       接下来需要将其加入到自己的代码中。方法很简单，只要在包含入口函数的.cpp文件中包含vld.h就可以。如果这个cpp文件包含了stdafx.h，则将包含vld.h的语句放在stdafx.h的包含语句之后，否则放在最前面。如下是一个示例程序：&lt;/div&gt;
&lt;div&gt;#include &amp;lt;vld.h&amp;gt;&lt;/div&gt;
&lt;div&gt;void main()&lt;/div&gt;
&lt;div&gt;{&lt;/div&gt;
&lt;div&gt;…&lt;/div&gt;
&lt;div&gt;}&lt;/div&gt;
&lt;div&gt;       接下来让我们来演示如何使用Visual Leak Detector检测内存泄漏。下面是一个简单的程序，用new分配了一个int大小的堆内存，并没有释放。其申请的内存地址用printf输出到屏幕上。&lt;/div&gt;
&lt;div&gt;#include &amp;lt;vld.h&amp;gt;&lt;/div&gt;
&lt;div&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;/div&gt;
&lt;div&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;void f()&lt;/div&gt;
&lt;div&gt;{&lt;/div&gt;
&lt;div&gt;    int *p = new int(0x12345678);&lt;/div&gt;
&lt;div&gt;    printf(&amp;quot;p=%08x, &amp;quot;, p);&lt;/div&gt;
&lt;div&gt;}&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;void main()&lt;/div&gt;
&lt;div&gt;{&lt;/div&gt;
&lt;div&gt;    f();&lt;/div&gt;
&lt;div&gt;}&lt;/div&gt;
&lt;div&gt;编译运行后，在标准输出窗口得到：&lt;/div&gt;
&lt;div&gt;p=003a89c0&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在Visual C++的Output窗口得到：&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;WARNING: Visual Leak Detector detected memory leaks!&lt;/div&gt;
&lt;div&gt;---------- Block 57 at 0x003A89C0: 4 bytes ----------  --57号块0x003A89C0地址泄漏了4个字节&lt;/div&gt;
&lt;div&gt;  Call Stack:                                               --下面是调用堆栈&lt;/div&gt;
&lt;div&gt;    d:\test\testvldconsole\testvldconsole\main.cpp (7): f  --表示在main.cpp第7行的f()函数&lt;/div&gt;
&lt;div&gt;    d:\test\testvldconsole\testvldconsole\main.cpp (14): main –双击以引导至对应代码处&lt;/div&gt;
&lt;div&gt;    f:\rtm\vctools\crt_bld\self_x86\crt\src\crtexe.c (586): __tmainCRTStartup&lt;/div&gt;
&lt;div&gt;    f:\rtm\vctools\crt_bld\self_x86\crt\src\crtexe.c (403): mainCRTStartup&lt;/div&gt;
&lt;div&gt;    0x7C816D4F (File and line number not available): RegisterWaitForInputIdle&lt;/div&gt;
&lt;div&gt;  Data:                                   --这是泄漏内存的内容，0x12345678&lt;/div&gt;
&lt;div&gt;    78 56 34 12                                                  xV4..... ........&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Visual Leak Detector detected 1 memory leak.    &lt;/div&gt;
&lt;div&gt;第二行表示57号块有4字节的内存泄漏，地址为0x003A89C0，根据程序控制台的输出，可以知道，该地址为指针p。程序的第7行，f()函数里，在该地址处分配了4字节的堆内存空间，并赋值为0x12345678，这样在报告中，我们看到了这4字节同样的内容。&lt;/div&gt;
&lt;div&gt;可以看出，对于每一个内存泄漏，这个报告列出了它的泄漏点、长度、分配该内存时的调用堆栈、和泄露内存的内容（分别以16进制和文本格式列出）。双击该堆栈报告的某一行，会自动在代码编辑器中跳到其所指文件的对应行。这些信息对于我们查找内存泄露将有很大的帮助。&lt;/div&gt;
&lt;div&gt;这是一个很方便易用的工具，安装后每次使用时，仅仅需要将它头文件包含进来重新build就可以。而且，该工具仅在build Debug版的时候会连接到你的程序中，如果build Release版，该工具不会对你的程序产生任何性能等方面影响。所以尽可以将其头文件一直包含在你的源代码中。&lt;/div&gt;
&lt;div&gt;Visual Leak Detector工作原理&lt;br&gt;       下面让我们来看一下该工具的工作原理。&lt;/div&gt;
&lt;div&gt;       在这之前，我们先来看一下Visual C++内置的内存泄漏检测工具是如何工作的。Visual C++内置的工具CRT Debug Heap工作原来很简单。在使用Debug版的malloc分配内存时，malloc会在内存块的头中记录分配该内存的文件名及行号。当程序退出时CRT会在main()函数返回之后做一些清理工作，这个时候来检查调试堆内存，如果仍然有内存没有被释放，则一定是存在内存泄漏。从这些没有被释放的内存块的头中，就可以获得文件名及行号。&lt;/div&gt;
&lt;div&gt;       这种静态的方法可以检测出内存泄漏及其泄漏点的文件名和行号，但是并不知道泄漏究竟是如何发生的，并不知道该内存分配语句是如何被执行到的。要想了解这些，就必须要对程序的内存分配过程进行动态跟踪。Visual Leak Detector就是这样做的。它在每次内存分配时将其上下文记录下来，当程序退出时，对于检测到的内存泄漏，查找其记录下来的上下文信息，并将其转换成报告输出。&lt;/div&gt;
&lt;div&gt;       &lt;/div&gt;
&lt;div&gt;初始化&lt;br&gt;       Visual Leak Detector要记录每一次的内存分配，而它是如何监视内存分配的呢？Windows提供了分配钩子(allocation hooks)来监视调试堆内存的分配。它是一个用户定义的回调函数，在每次从调试堆分配内存之前被调用。在初始化时，Visual Leak Detector使用_CrtSetAllocHook注册这个钩子函数，这样就可以监视从此之后所有的堆内存分配了。&lt;/div&gt;
&lt;div&gt;       如何保证在Visual Leak Detector初始化之前没有堆内存分配呢？全局变量是在程序启动时就初始化的，如果将Visual Leak Detector作为一个全局变量，就可以随程序一起启动。但是C/C++并没有约定全局变量之间的初始化顺序，如果其它全局变量的构造函数中有堆内存分配，则可能无法检测到。Visual Leak Detector使用了C/C++提供的#pragma init_seg来在某种程度上减少其它全局变量在其之前初始化的概率。根据#pragma init_seg的定义，全局变量的初始化分三个阶段：首先是compiler段，一般c语言的运行时库在这个时候初始化；然后是lib段，一般用于第三方的类库的初始化等；最后是user段，大部分的初始化都在这个阶段进行。Visual Leak Detector将其初始化设置在compiler段，从而使得它在绝大多数全局变量和几乎所有的用户定义的全局变量之前初始化。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;记录内存分配&lt;br&gt;       一个分配钩子函数需要具有如下的形式：&lt;/div&gt;
&lt;div&gt;int YourAllocHook( int allocType, void *userData, size_t size, int blockType, long requestNumber, const unsigned char *filename, int lineNumber);&lt;/div&gt;
&lt;div&gt;       就像前面说的，它在Visual Leak Detector初始化时被注册，每次从调试堆分配内存之前被调用。这个函数需要处理的事情是记录下此时的调用堆栈和此次堆内存分配的唯一标识——requestNumber。&lt;/div&gt;
&lt;div&gt;       得到当前的堆栈的二进制表示并不是一件很复杂的事情，但是因为不同体系结构、不同编译器、不同的函数调用约定所产生的堆栈内容略有不同，要解释堆栈并得到整个函数调用过程略显复杂。不过windows提供一个StackWalk64函数，可以获得堆栈的内容。StackWalk64的声明如下：&lt;/div&gt;
&lt;div&gt;BOOL StackWalk64(&lt;br&gt;  DWORD MachineType,&lt;br&gt;  HANDLE hProcess,&lt;br&gt;  HANDLE hThread,&lt;br&gt;  LPSTACKFRAME64 StackFrame,&lt;br&gt;  PVOID ContextRecord,&lt;br&gt;  PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,&lt;br&gt;  PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,&lt;br&gt;  PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,&lt;br&gt;  PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress&lt;br&gt;);&lt;br&gt;STACKFRAME64结构表示了堆栈中的一个frame。给出初始的STACKFRAME64，反复调用该函数，便可以得到内存分配点的调用堆栈了。&lt;/div&gt;
&lt;div&gt;    // Walk the stack.&lt;/div&gt;
&lt;div&gt;    while (count &amp;lt; _VLD_maxtraceframes) {&lt;/div&gt;
&lt;div&gt;        count++;&lt;/div&gt;
&lt;div&gt;        if (!pStackWalk64(architecture, m_process, m_thread, &amp;amp;frame, &amp;amp;context,&lt;/div&gt;
&lt;div&gt;                          NULL, pSymFunctionTableAccess64, pSymGetModuleBase64, NULL)) {&lt;/div&gt;
&lt;div&gt;            // Couldn't trace back through any more frames.&lt;/div&gt;
&lt;div&gt;            break;&lt;/div&gt;
&lt;div&gt;        }&lt;/div&gt;
&lt;div&gt;        if (frame.AddrFrame.Offset == 0) {&lt;/div&gt;
&lt;div&gt;            // End of stack.&lt;/div&gt;
&lt;div&gt;            break;&lt;/div&gt;
&lt;div&gt;        }&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;        // Push this frame's program counter onto the provided CallStack.&lt;/div&gt;
&lt;div&gt;        callstack-&amp;gt;push_back((DWORD_PTR)frame.AddrPC.Offset);&lt;/div&gt;
&lt;div&gt;    }&lt;/div&gt;
&lt;div&gt;       那么，如何得到初始的STACKFRAME64结构呢？在STACKFRAME64结构中，其他的信息都比较容易获得，而当前的程序计数器(EIP)在x86体系结构中无法通过软件的方法直接读取。Visual Leak Detector使用了一种方法来获得当前的程序计数器。首先，它调用一个函数，则这个函数的返回地址就是当前的程序计数器，而函数的返回地址可以很容易的从堆栈中拿到。下面是Visual Leak Detector获得当前程序计数器的程序：&lt;/div&gt;
&lt;div&gt;#if defined(_M_IX86) || defined(_M_X64)&lt;/div&gt;
&lt;div&gt;#pragma auto_inline(off)&lt;/div&gt;
&lt;div&gt;DWORD_PTR VisualLeakDetector::getprogramcounterx86x64 ()&lt;/div&gt;
&lt;div&gt;{&lt;/div&gt;
&lt;div&gt;    DWORD_PTR programcounter;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;    __asm mov AXREG, [BPREG + SIZEOFPTR] // Get the return address out of the current stack frame&lt;/div&gt;
&lt;div&gt;    __asm mov [programcounter], AXREG    // Put the return address into the variable we'll return&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;    return programcounter;&lt;/div&gt;
&lt;div&gt;}&lt;/div&gt;
&lt;div&gt;#pragma auto_inline(on)&lt;/div&gt;
&lt;div&gt;#endif // defined(_M_IX86) || defined(_M_X64)&lt;/div&gt;
&lt;div&gt;       得到了调用堆栈，自然要记录下来。Visual Leak Detector使用一个类似map的数据结构来记录该信息。这样可以方便的从requestNumber查找到其调用堆栈。分配钩子函数的allocType参数表示此次堆内存分配的类型，包括_HOOK_ALLOC, _HOOK_REALLOC, 和 _HOOK_FREE，下面代码是Visual Leak Detector对各种情况的处理。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;    switch (type) {&lt;/div&gt;
&lt;div&gt;    case _HOOK_ALLOC:&lt;/div&gt;
&lt;div&gt;        visualleakdetector.hookmalloc(request);&lt;/div&gt;
&lt;div&gt;        break;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;    case _HOOK_FREE:&lt;/div&gt;
&lt;div&gt;        visualleakdetector.hookfree(pdata);&lt;/div&gt;
&lt;div&gt;        break;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;    case _HOOK_REALLOC:&lt;/div&gt;
&lt;div&gt;        visualleakdetector.hookrealloc(pdata, request);&lt;/div&gt;
&lt;div&gt;        break;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;    default:&lt;/div&gt;
&lt;div&gt;        visualleakdetector.report(&amp;quot;WARNING: Visual Leak Detector: in allochook(): Unhandled allocation type (%d).\n&amp;quot;, type);&lt;/div&gt;
&lt;div&gt;        break;&lt;/div&gt;
&lt;div&gt;    }&lt;/div&gt;
&lt;div&gt;这里，hookmalloc()函数得到当前堆栈，并将当前堆栈与requestNumber加入到类似map的数据结构中。hookfree()函数从类似map的数据结构中删除该信息。hookrealloc()函数依次调用了hookfree()和hookmalloc()。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;检测内存泄露&lt;br&gt;       前面提到了Visual C++内置的内存泄漏检测工具的工作原理。与该原理相同，因为全局变量以构造的相反顺序析构，在Visual Leak Detector析构时，几乎所有的其他变量都已经析构，此时如果仍然有未释放之堆内存，则必为内存泄漏。&lt;/div&gt;
&lt;div&gt;       分配的堆内存是通过一个链表来组织的，检查内存泄漏则是检查此链表。但是windows没有提供方法来访问这个链表。Visual Leak Detector使用了一个小技巧来得到它。首先在堆上申请一块临时内存，则该内存的地址可以转换成指向一个_CrtMemBlockHeader结构，在此结构中就可以获得这个链表。代码如下：&lt;/div&gt;
&lt;div&gt;    char *pheap = new char;&lt;/div&gt;
&lt;div&gt;    _CrtMemBlockHeader *pheader = pHdr(pheap)-&amp;gt;pBlockHeaderNext;&lt;/div&gt;
&lt;div&gt;delete pheap;&lt;/div&gt;
&lt;div&gt;其中pheader则为链表首指针。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;报告生成&lt;br&gt;       前面讲了Visual Leak Detector如何检测、记录内存泄漏及其其调用堆栈。但是如果要这个信息对程序员有用的话，必须转换成可读的形式。Visual Leak Detector使用SymGetLineFromAddr64()及SymFromAddr()生成可读的报告。&lt;/div&gt;
&lt;div&gt;            // Iterate through each frame in the call stack.&lt;/div&gt;
&lt;div&gt;            for (frame = 0; frame &amp;lt; callstack-&amp;gt;size(); frame++) {&lt;/div&gt;
&lt;div&gt;                // Try to get the source file and line number associated with&lt;/div&gt;
&lt;div&gt;                // this program counter address.&lt;/div&gt;
&lt;div&gt;                if (pSymGetLineFromAddr64(m_process, &lt;/div&gt;
&lt;div&gt;                   (*callstack)[frame], &amp;amp;displacement, &amp;amp;sourceinfo)) {&lt;/div&gt;
&lt;div&gt;                    ...&lt;/div&gt;
&lt;div&gt;                }&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;                // Try to get the name of the function containing this program&lt;/div&gt;
&lt;div&gt;                // counter address.&lt;/div&gt;
&lt;div&gt;                if (pSymFromAddr(m_process, (*callstack)[frame], &lt;/div&gt;
&lt;div&gt;                    &amp;amp;displacement64, pfunctioninfo)) {&lt;/div&gt;
&lt;div&gt;                    functionname = pfunctioninfo-&amp;gt;Name;&lt;/div&gt;
&lt;div&gt;                }&lt;/div&gt;
&lt;div&gt;                else {&lt;/div&gt;
&lt;div&gt;                    functionname = &amp;quot;(Function name unavailable)&amp;quot;;&lt;/div&gt;
&lt;div&gt;                }&lt;/div&gt;
&lt;div&gt;                ...&lt;/div&gt;
&lt;div&gt;            }&lt;/div&gt;
&lt;div&gt;       概括讲来，Visual Leak Detector的工作分为3步，首先在初始化注册一个钩子函数；然后在内存分配时该钩子函数被调用以记录下当时的现场；最后检查堆内存分配链表以确定是否存在内存泄漏并将泄漏内存的现场转换成可读的形式输出。有兴趣的读者可以阅读Visual Leak Detector的源代码。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;总结&lt;br&gt;       在使用上，Visual Leak Detector简单方便，结果报告一目了然。在原理上，Visual Leak Detector针对内存泄漏问题的特点，可谓对症下药——内存泄漏不是不容易发现吗？那就每次内存分配是都给记录下来，程序退出时算总账；内存泄漏现象出现时不是已时过境迁，并非当时泄漏点的现场了吗？那就把现场也记录下来，清清楚楚的告诉使用者那块泄漏的内存就是在如何一个调用过程中泄漏掉的。&lt;/div&gt;
&lt;div&gt;       Visual Leak Detector是一个简单易用内存泄漏检测工具。现在最新的版本是1.9a，采用了新的检测机制，并在功能上有了很多改进。读者不妨体验一下。&lt;br&gt; &lt;br&gt;&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+%e4%bd%bf%e7%94%a8Visual+Leak+Detector%e6%a3%80%e6%b5%8b%e5%86%85%e5%ad%98%e6%b3%84%e6%bc%8f+(%e8%bd%ac)&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1020.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1020.entry</guid><pubDate>Fri, 28 Sep 2007 03:13:02 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1020/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1020.entry#comment</wfw:comment><dcterms:modified>2007-09-28T03:13:02Z</dcterms:modified></item><item><title>UltraEdit32 &amp; SciTE 挂接C编译器</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1018.entry</link><description>&lt;div&gt;  &lt;br&gt;标题   UltraEdit32 &amp;amp; SciTE 挂接C编译器     选择自 uuzhang 的 Blog  &lt;br&gt;关键字   UltraEdit32 &amp;amp; SciTE 挂接C编译器 &lt;br&gt;出处    &lt;br&gt; &lt;br&gt;          UltraEdit32  &amp;amp;  SciTE  &lt;br&gt;              挂接C编译器&lt;br&gt;                                                        碎心竹&lt;br&gt;-----------------------------------------------------------------------------&lt;/div&gt;
&lt;div&gt;&lt;br&gt;UltraEdit32 是一种大家常用的源文件编辑查看工具  &lt;br&gt;速度快 语法着色 ASCII码表    等功能很受欢迎 &lt;/div&gt;
&lt;div&gt;SciTE 是现在一些程序员喜欢的TE工具是在unix/linux&lt;br&gt;环境下制作的工具有其win32版本 而且是开源软件 &lt;br&gt;其界面 作的很简单 编辑界面有种很特别的感觉&lt;br&gt;最主要就是他的启动速度 快&lt;/div&gt;
&lt;div&gt;下面详细介绍一下 怎么用UE挂接 bcb5.5编译器&lt;br&gt;因为bcb5.5 是免费的 到处都有 而且非常小&lt;br&gt;还可以编译 win32程序 &lt;/div&gt;
&lt;div&gt;这两个工具下载安装都很简单 主要在设置上&lt;br&gt;编译器有一些设置 需要自己做&lt;/div&gt;
&lt;div&gt;在borland主页上下载bcb5.5并解压后 &lt;br&gt;在其目录/bin下面要手工创建两个配置文件&lt;br&gt;这个在其帮助文件中说得很明白&lt;br&gt;bcc32.cfg 和 ilink32.cfg&lt;br&gt;以我电脑为例 我解压到E盘 bcc5目录&lt;br&gt;在 e:\bcc5\bin\ 下&lt;br&gt;创建 bcc32.cfg 和 ilink32.cfg &lt;/div&gt;
&lt;div&gt;bcc32.cfg 内容如下:&lt;br&gt;-I&amp;quot;E:\bcc5\include&amp;quot;&lt;br&gt;-L&amp;quot;E:\bcc5\lib&amp;quot;&lt;/div&gt;
&lt;div&gt;ilink32.cfg内容如下:&lt;br&gt;-L&amp;quot;E:\bcc5\Lib&amp;quot;&lt;/div&gt;
&lt;div&gt;完成后&lt;br&gt;就可以配置 UE 和 SciTE 来挂接bcb5.5了&lt;br&gt;UE比较简单&lt;/div&gt;
&lt;div&gt;在 高级 菜单 找到 工具栏配置 打开&lt;br&gt;首先是 编译&lt;br&gt;命令行填入: &lt;br&gt;E:\bcc5\Bin\bcc32 -y -v -c -o&amp;quot;%n.obj&amp;quot; &amp;quot;%f&amp;quot;&lt;br&gt;工作目录填入:&lt;br&gt;%p&lt;br&gt;菜单项名称填入:&lt;br&gt;编译&lt;/div&gt;
&lt;div&gt;选项 点上 输出到列表框口 显示dos窗口 捕捉输出&lt;/div&gt;
&lt;div&gt;点击插入 OK  完成一个&lt;/div&gt;
&lt;div&gt;&lt;br&gt;下一个 连接 菜单 这个要注意 因为dos程序和win32程序&lt;/div&gt;
&lt;div&gt;连接命令是不同的 可以制作两个菜单 第一个dos连接&lt;/div&gt;
&lt;div&gt;命令行填入:&lt;br&gt;E:\bcc5\Bin\ilink32 -v &amp;quot;%n.obj&amp;quot; import32.lib cw32.lib c0x32.obj /ap&lt;br&gt;工作目录填入:&lt;br&gt;%p&lt;br&gt;菜单项名称填入:&lt;br&gt;dos连接&lt;/div&gt;
&lt;div&gt;选项 点上 输出到列表框口 显示dos窗口 捕捉输出&lt;br&gt;点击插入&lt;/div&gt;
&lt;div&gt;然后是 win32连接&lt;br&gt;命令行填入:&lt;br&gt;E:\bcc5\Bin\ilink32 -v &amp;quot;%n.obj&amp;quot;  import32.lib cw32.lib c0w32.obj /aa&lt;br&gt;工作目录填入:&lt;br&gt;%p&lt;br&gt;菜单项名称填入:&lt;br&gt;win32连接&lt;br&gt;选项 点上 输出到列表框口 显示dos窗口 捕捉输出&lt;br&gt;点击插入&lt;/div&gt;
&lt;div&gt;&lt;br&gt;连接命令完成 下面作个运行命令 &lt;br&gt;但是因为dos和win32在UE里面的运行还有一些不同  最好还是作两个&lt;/div&gt;
&lt;div&gt;dos运行&lt;br&gt;命令行填入:&lt;br&gt;%n.exe&lt;br&gt;工作目录填入:&lt;br&gt;%p&lt;br&gt;菜单项名称填入:&lt;br&gt;DOS运行&lt;br&gt;选项 点上 输出到列表框口 显示dos窗口 捕捉输出&lt;br&gt;点击插入&lt;/div&gt;
&lt;div&gt;win32运行&lt;br&gt;命令行填入:&lt;br&gt;%n.exe&lt;br&gt;工作目录填入:&lt;br&gt;%p&lt;br&gt;菜单项名称填入:&lt;br&gt;win32运行&lt;br&gt;选项 点上 windows程序 &lt;br&gt;点击插入&lt;/div&gt;
&lt;div&gt;&lt;br&gt;好 UE还差最后一项 那就是清理临时文件&lt;/div&gt;
&lt;div&gt;win32运行&lt;br&gt;命令行填入:&lt;br&gt;del *.obj *.map *.ilc *.ild *.ilf *.ils *.tds&lt;br&gt;工作目录填入:&lt;br&gt;%p&lt;br&gt;菜单项名称填入:&lt;br&gt;清除临时文件&lt;br&gt;选项 点上 输出到列表框口 显示dos窗口 捕捉输出&lt;br&gt;点击插入&lt;/div&gt;
&lt;div&gt;大功告成 可以测试一下了&lt;/div&gt;
&lt;div&gt;然后是稍微复杂的 SciTE&lt;br&gt;对 SciTE 也不知道该怎么说 反正我弄了N长时间 才弄明白&lt;br&gt;还是有点成就感 嘿嘿 不过还是有一些地方没弄明白&lt;br&gt;等学好编程 自己修改它 嘿嘿 反正是开源的&lt;br&gt;SciTE 的网址是&lt;br&gt;&lt;a href="http://www.scintilla.org/SciTE.html"&gt;http://www.scintilla.org/SciTE.html&lt;/a&gt;&lt;br&gt;可以在它网站找到 中文的配置文件 弄好就是中文版的了 &lt;br&gt;配置文件说的很明白   这里就不多说了&lt;/div&gt;
&lt;div&gt;配置编译器 不多说啥 就是 直接复制过去好了&lt;br&gt;也不用研究怎么配置他的了 都是鹰语 &lt;br&gt;主要是文件的选择  SciTE 的配置文件带了一堆&lt;br&gt;一开始还真有点不习惯  如果你下载的是完整的压缩版&lt;br&gt;非源程序版 解压缩之后能在其目录找到 cpp.properties&lt;br&gt;这个是C/C++等配制文件 打开之后&lt;br&gt;找到 &lt;br&gt;cc= &lt;br&gt;build=&lt;br&gt;从这开始粘贴下面内容&lt;br&gt;cc=E:\bcc5\Bin\bcc32 -y -v -c -o&amp;quot;$(FileDir)\$(FileName).obj&amp;quot; &amp;quot;$(FileDir)\$(FileNameExt)&amp;quot;&lt;br&gt;build=E:\bcc5\Bin\ilink32 -v &amp;quot;$(FileDir)\$(FileName).obj&amp;quot;  import32.lib cw32.lib c0x32.obj /ap&lt;br&gt;buildw=E:\bcc5\Bin\ilink32 -v &amp;quot;$(FileDir)\$(FileName).obj&amp;quot;  import32.lib cw32.lib c0w32.obj /aa&lt;/div&gt;
&lt;div&gt;&lt;br&gt;command.compile.*.c=$(cc)&lt;br&gt;command.build.*.c=$(build)&lt;br&gt;command.go.*.c=$(FileName)&lt;/div&gt;
&lt;div&gt;command.compile.*.c=$(cc)&lt;br&gt;command.build.*.c=$(build)&lt;br&gt;command.go.*.c=$(FileName)&lt;/div&gt;
&lt;div&gt;command.compile.*.cc=$(cc)&lt;br&gt;command.build.*.cc=$(build)&lt;br&gt;command.go.*.cc=$(FileName)&lt;/div&gt;
&lt;div&gt;command.compile.*.cpp=$(cc)&lt;br&gt;command.build.*.cpp=$(build)&lt;br&gt;command.go.*.cpp=$(FileName)&lt;/div&gt;
&lt;div&gt;command.compile.*.cxx=$(cc)&lt;br&gt;command.build.*.cxx=$(build)&lt;br&gt;command.go.*.cxx=$(FileName)&lt;/div&gt;
&lt;div&gt;command.go.subsystem.*=2&lt;br&gt;command.build.*.h=make&lt;/div&gt;
&lt;div&gt;command.name.3.*.c=生成Win&lt;br&gt;command.3.*.c=$(buildw)&lt;br&gt;command.subsystem.3.*.c=0&lt;/div&gt;
&lt;div&gt;command.name.3.*.cpp=生成Win&lt;br&gt;command.3.*.cpp=$(buildw)&lt;br&gt;command.subsystem.3.*.cpp=0&lt;/div&gt;
&lt;div&gt;command.name.0.*=清除temp&lt;br&gt;command.0.*=$(FileDir)\dd.bat&lt;br&gt;command.subsystem.0.*=0&lt;/div&gt;
&lt;div&gt;上面的dd.bat 是自己手工创建的 SciTE好像是不支持del *.obj&lt;br&gt;之类的dos命令 只能作个批处理来输出temp文件 很麻烦&lt;br&gt;不知道有谁能很好的解决这个问题&lt;/div&gt;
&lt;div&gt;&lt;br&gt;这样就可以正常的编译了调试了  如果你下载的SciTE界面使用还有问题&lt;br&gt;不要怪SciTE有问题, SciTE的所有功能的是通过配制文件修改的 &lt;br&gt;下面列举一些修改选项  点选项 打开全局设置文件&lt;/div&gt;
&lt;div&gt;修改 tab &lt;br&gt;选项在 # Indentation 下面&lt;br&gt;tabsize=8      tab显示长度&lt;br&gt;indent.size=4  按tab填充长度&lt;br&gt;use.tabs=0     是非使用tab缩进&lt;br&gt;# Internationalisation 这下面有字体代码设置&lt;br&gt;如果你用的是win2000 只用设置code.page=936&lt;br&gt;就成了 别的系统好像还要改character.set=&lt;br&gt;这个看看中文配制文件上的说明就能懂了&lt;/div&gt;
&lt;div&gt;toolbar.visible=1  工具栏打开&lt;br&gt;position.width=800&lt;br&gt;position.height=575  这两项能修改启动SciTE时的窗口大小根据你的分辨率调整&lt;br&gt;split.vertical=0     外部捕捉输出 的显示 1 右侧 0 下面&lt;br&gt;# Element styles  的下面&lt;br&gt;有一些选项能修改编辑界面的颜色 显示方式等 可是试着修改&lt;/div&gt;
&lt;div&gt;ok了 可以测试了&lt;br&gt;                              2005.7.13&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;作者Blog：&lt;a href="http://blog.csdn.net/uuzhang/"&gt;http://blog.csdn.net/uuzhang/&lt;/a&gt;&lt;br&gt; &lt;br&gt; &lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+UltraEdit32+%26+SciTE+%e6%8c%82%e6%8e%a5C%e7%bc%96%e8%af%91%e5%99%a8&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1018.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1018.entry</guid><pubDate>Fri, 07 Sep 2007 05:15:27 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1018/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1018.entry#comment</wfw:comment><dcterms:modified>2007-09-07T05:15:27Z</dcterms:modified></item><item><title>C#中调用C++的dll的参数为指针类型的导出函数（包括二级指针的情况） (转)</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1015.entry</link><description>&lt;div&gt; C#中调用C++的dll的参数为指针类型的导出函数（包括二级指针的情况） (转)&lt;/div&gt;
&lt;div&gt;摘自: &lt;a href="http://www.cppblog.com/kerlw/archive/2007/06/27/27061.html"&gt;http://www.cppblog.com/kerlw/archive/2007/06/27/27061.html&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;C#中调用C++的dll的参数为指针类型的导出函数（包括二级指针的情况） &lt;br&gt;         严格来说这篇文章算不上C++范围的，不过还是挂了点边，还是在自己的blog中记录一下吧。&lt;/div&gt;
&lt;div&gt;         C++中使用指针是家常便饭了，也非常的好用，这也是我之所以喜欢C++的原因之一。但是在C#中就强调托管的概念了，指针就不用想了。本来如果就在C#的世界里面写代码，也还算舒服，但是万事万物总有联系，这不，现在公司的另外一个用C#作的项目就碰到问题了，要调用之前用C++写的一个DLL中的一些函数，很多函数的参数都是指针类型的，这下可麻烦咯，公司里做C#的都是刚起步，C++又只有我最熟悉，这项技术研究工作又光荣的落到我身上。&lt;/div&gt;
&lt;div&gt;        我对C#也不甚熟悉，所以也许我的方法不一定是最直接的，但是测试的结果是满足了这个调用需要了的。下面我就详细介绍一下。&lt;/div&gt;
&lt;div&gt;        使用unsafe、fix等关键字应该是能够实现的，但是他们项目组要求不用这个，所以我也没深入去试验。除了这个方法，应该来说是有两个思路的，第一个思路可能看起来比较直接，使用ref，ref这个关键字似乎有点特殊性，字面上理解似乎应该和C++中的引用类型相对应，不过似乎它还是有一定特殊性的，貌似以前看到过一篇文章说ref会自己去判断是引用类型还是指针，我尝试了一下，果然是可行的。但是对于有二级指针的情况ref也就不灵了~这就导出了我的另一个思路，使用Marshal。&lt;/div&gt;
&lt;div&gt;下面我们还是代码说明问题：&lt;br&gt;以下是C++DLL中的代码片断，主要是使用到的两个结构的定义，以及导出函数TestFunction的定义。&lt;/div&gt;
&lt;div&gt;&lt;br&gt;C++ DLL中的代码片断&lt;br&gt;#pragma pack(push)&lt;br&gt;#pragma pack(1)&lt;br&gt;typedef struct EmmStruct {&lt;br&gt;    int len;&lt;br&gt;} EMMSTRUCT, *LPEMMSTRUCT;&lt;/div&gt;
&lt;div&gt;typedef struct MyStruct {&lt;br&gt;    int iParam;&lt;br&gt;    long size;&lt;br&gt;    LPEMMSTRUCT lpEmmStructArr;&lt;br&gt;} MYSTRUCT, *LPMYSTRUCT;&lt;br&gt;#pragma pack(pop)&lt;/div&gt;
&lt;div&gt;extern &amp;quot;C&amp;quot; void __declspec(dllexport) __stdcall  TestFunction(LPMYSTRUCT lpMyStruct)&lt;br&gt;{&lt;br&gt;    lpMyStruct-&amp;gt;iParam = 100;&lt;br&gt;    lpMyStruct-&amp;gt;size = 10;&lt;br&gt;    lpMyStruct-&amp;gt;lpEmmStructArr = new EMMSTRUCT[lpMyStruct-&amp;gt;size];&lt;br&gt;    for(int i=0;i&amp;lt;lpMyStruct-&amp;gt;size;i++) {&lt;br&gt;        lpMyStruct-&amp;gt;lpEmmStructArr[i].len = i;&lt;br&gt;    }&lt;br&gt;}&lt;/div&gt;
&lt;div&gt;那么再来看看C#中调用的代码：&lt;br&gt;C#中调用的代码片断using System;&lt;br&gt;using System.Collections.Generic;&lt;br&gt;using System.Text;&lt;br&gt;using System.Runtime.InteropServices;      //使用C#导入dll必须的&lt;/div&gt;
&lt;div&gt;namespace csharptest&lt;br&gt;{&lt;br&gt;    //StructLayout和FieldOffset这些设置不是必须的，只是为了防止对齐的问题最好加上，这样自己心里有数对齐到哪一位&lt;br&gt;    [StructLayout(LayoutKind.Explicit)]&lt;br&gt;    public struct EmmStruct&lt;br&gt;    {&lt;br&gt;        [FieldOffset(0)]&lt;br&gt;        public int len;&lt;br&gt;    }&lt;/div&gt;
&lt;div&gt;    [StructLayout(LayoutKind.Explicit)]&lt;br&gt;    public struct MyStruct&lt;br&gt;    {&lt;br&gt;        [FieldOffset(0)]&lt;br&gt;        public int iParam;&lt;br&gt;        [FieldOffset(4)]&lt;br&gt;        public int size;&lt;br&gt;        [FieldOffset(8)]&lt;br&gt;        public IntPtr ptrEmmStruct;&lt;br&gt;    }&lt;/div&gt;
&lt;div&gt;    class Program&lt;br&gt;    {&lt;br&gt;         // dll中导出函数的声明&lt;br&gt;        [DllImport(&amp;quot;dllforcsharp.dll&amp;quot;, CallingConvention=CallingConvention.Winapi)]&lt;br&gt;        public extern static void TestFunction(IntPtr ptr);&lt;/div&gt;
&lt;div&gt;        static void Main(string[] args)&lt;br&gt;        {&lt;br&gt;            try&lt;br&gt;            {&lt;br&gt;                MyStruct s = new MyStruct();&lt;br&gt;                IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(s));&lt;br&gt;                Marshal.StructureToPtr(s, ptr, false);&lt;/div&gt;
&lt;div&gt;                TestFunction(ptr);&lt;/div&gt;
&lt;div&gt;                s = (MyStruct)Marshal.PtrToStructure(ptr, typeof(MyStruct));&lt;/div&gt;
&lt;div&gt;                EmmStruct ret;&lt;br&gt;                for (int i = 0; i &amp;lt; s.size; i++)&lt;br&gt;                {&lt;br&gt;                    IntPtr ptr2 = new IntPtr(s.ptrEmmStruct.ToInt32() + 4 * i);&lt;br&gt;                    ret = (EmmStruct)Marshal.PtrToStructure(ptr2, typeof(EmmStruct));&lt;br&gt;                }&lt;/div&gt;
&lt;div&gt;                Marshal.FreeHGlobal(ptr);&lt;br&gt;            }&lt;br&gt;            catch (Exception e)&lt;br&gt;            {&lt;br&gt;                string str = e.Message;&lt;br&gt;            }&lt;br&gt;            finally&lt;br&gt;            {&lt;br&gt;            }&lt;br&gt;        }&lt;br&gt;    }&lt;br&gt;}&lt;/div&gt;
&lt;div&gt;代码也不多，而且从字面的意思就能知道是干什么的了，所以我就没写注释。用这种方法就实现了参数中含有二级指针的情况。要注意的就是C#中的long和C++中不同，它占8字节。所以一般情况下C++中long的，C#里面用int或者int32就ok了。我自己对C#不是特别熟悉，所以可能也未能完全讲解清楚，甚至可能存在漏洞，有高人见到的话，可以指点指点。&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+C%23%e4%b8%ad%e8%b0%83%e7%94%a8C%2b%2b%e7%9a%84dll%e7%9a%84%e5%8f%82%e6%95%b0%e4%b8%ba%e6%8c%87%e9%92%88%e7%b1%bb%e5%9e%8b%e7%9a%84%e5%af%bc%e5%87%ba%e5%87%bd%e6%95%b0%ef%bc%88%e5%8c%85%e6%8b%ac%e4%ba%8c%e7%ba%a7%e6%8c%87%e9%92%88%e7%9a%84%e6%83%85%e5%86%b5%ef%bc%89+(%e8%bd%ac)&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1015.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1015.entry</guid><pubDate>Thu, 02 Aug 2007 02:07:54 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1015/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1015.entry#comment</wfw:comment><dcterms:modified>2007-08-02T02:07:54Z</dcterms:modified></item><item><title>获取显卡相关信息</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1014.entry</link><description>&lt;p&gt;获取显卡相关信息:
&lt;p&gt;void GetVideoCardInfo()&lt;br&gt;{&lt;br&gt; LPDIRECT3D9 pD3D = NULL;  // Used to create the D3DDevice
&lt;p&gt; pD3D = Direct3DCreate9(D3D_SDK_VERSION); //Direct3D9.
&lt;p&gt; D3DADAPTER_IDENTIFIER9 d3dAdapterIdentifier;&lt;br&gt; D3DDISPLAYMODE         d3dDmDesktop;
&lt;p&gt; DWORD m_dwNumAdapters = pD3D-&amp;gt;GetAdapterCount();&lt;br&gt; for( UINT iAdapter = 0; iAdapter&amp;lt;m_dwNumAdapters; iAdapter++ )&lt;br&gt; {&lt;br&gt;  // Fill in adapter info&lt;br&gt;  pD3D-&amp;gt;GetAdapterIdentifier( iAdapter, D3DENUM_WHQL_LEVEL, &amp;amp;d3dAdapterIdentifier );&lt;br&gt;  pD3D-&amp;gt;GetAdapterDisplayMode( iAdapter, &amp;amp;d3dDmDesktop );&lt;br&gt;  char szBuf[256];&lt;br&gt;  sprintf(szBuf, &amp;quot;第%d个适配器: %s, 显示宽度: %d, 显示高度: %d&amp;quot;, iAdapter, d3dAdapterIdentifier.Description, d3dDmDesktop.Width, d3dDmDesktop.Height);&lt;br&gt;  MessageBox(0, szBuf, &amp;quot;显示模式&amp;quot;, MB_OK|MB_ICONINFORMATION);&lt;br&gt; }
&lt;p&gt; SAFE_RELEASE( pD3D );&lt;br&gt;}
&lt;p&gt;&lt;br&gt;参考:&lt;br&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/bb174317.aspx"&gt;http://msdn2.microsoft.com/en-us/library/bb174317.aspx&lt;/a&gt;&lt;br&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/bb174318.aspx"&gt;http://msdn2.microsoft.com/en-us/library/bb174318.aspx&lt;/a&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+%e8%8e%b7%e5%8f%96%e6%98%be%e5%8d%a1%e7%9b%b8%e5%85%b3%e4%bf%a1%e6%81%af&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1014.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1014.entry</guid><pubDate>Fri, 27 Jul 2007 06:16:16 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1014/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1014.entry#comment</wfw:comment><dcterms:modified>2007-07-27T06:54:56Z</dcterms:modified></item><item><title>遍历和查找外部程序 Tree-View 中的项目(转)</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1012.entry</link><description>&lt;div&gt;遍历和查找外部程序 Tree-View 中的项目(转)&lt;br&gt;来自:http://www.vckbase.com/document/viewdoc/?id=1712&lt;/div&gt;
&lt;div&gt;遍历和查找外部程序 Tree-View 中的项目&lt;/div&gt;
&lt;div&gt;天津 赵春生&lt;/div&gt;
&lt;div&gt;下载源代码&lt;/div&gt;
&lt;div&gt;　　《金山词霸2002》中的附录收集了很多古诗，有时为了寻找一篇古诗，得找很久很久（俺文科很差）。观察其附录的结构，发现是个Tree-View控件，如果能查找里面的项目该有多好，可这个功能软件本身却并没有提供（不知道现在最新的版本是否已经提供了这个功能，如果没有，赶快加上吧，顺便奖励俺一套该产品的最新版，哈哈）……问题出来了：我们要编写一个程序，让她在外部程序中的Tree-View控件里，按用户指定的项目名称顺序查找其中的项目。&lt;br&gt;　　要查找首先得遍历，连范围都确定不好何谈查找？所以本篇分两部分进行讲解：第一部分解决遍历的问题；第二部分解决查找指定项目的问题。&lt;/div&gt;
&lt;div&gt;第一部分：遍历外部程序Tree-View中的项目&lt;/div&gt;
&lt;div&gt;一：程序说明：&lt;/div&gt;
&lt;div&gt;如图一所示Tree-View控件的典型结构图，我们将按照图示的顺序来遍历其中的项目。&lt;/div&gt;
&lt;div&gt;&lt;br&gt;图一&lt;/div&gt;
&lt;div&gt;翻阅SDK手册中关于Tree-View控件的相关章节，发现了几个有用的消息：&lt;/div&gt;
&lt;div&gt;TVM_GETNEXTITEM：得到项目的句柄（参数：TVGN_ROOT得到根句柄，TVGN_NEXTVISIBLE得到下一个可见项目的句柄）； &lt;br&gt;TVM_EXPAND：展开或折叠指定项目（参数：TVE_EXPAND展开指定项目）； &lt;br&gt;TVM_SELECTITEM：选中指定项目。 &lt;br&gt;利用这些消息和SendMessage()函数，我们可以很容易写出遍历代码。&lt;/div&gt;
&lt;div&gt;二：具体实践&lt;/div&gt;
&lt;div&gt;　　在本文所提供的DEMO中，有一段将十六进制字符串转换成十进制无符号长整型的代码，作用是将用户输入的十六进制TV句柄值转换成十进制并存放在变量dec_sum中。此代码不列入本文讨论的范畴，大家不闲弱智的话就将就着用吧。下面是实现遍历功能的关键代码： &lt;/div&gt;
&lt;div&gt; /* Tree-View Control_Demo_SeqShow 1.0 版&lt;br&gt; * 版权所有 (C) 2006 天津 赵春生&lt;br&gt; * 2006.08.28&lt;br&gt; * &lt;a href="http://timw.yeah.net/"&gt;http://timw.yeah.net&lt;/a&gt;&lt;br&gt; * &lt;a href="http://timw.126.com/"&gt;http://timw.126.com&lt;/a&gt;&lt;br&gt; * 本程序能顺序遍历TV控件中的所有项目。&lt;br&gt; * 代码在Win2000P+SP4 + VC6+SP6测试通过。&lt;br&gt; */&lt;/div&gt;
&lt;div&gt; if(error==0)//如果在数据验证转换的过程中未出现错误（error==0时无错误）&lt;br&gt; {&lt;br&gt;  &lt;br&gt;  //下面为核心部分：顺序显示（选中）指定Tree-View控件中的所有Item.&lt;br&gt;  &lt;br&gt;  hwnd=HWND(dec_sum);//得到转换后的数据&lt;br&gt;  &lt;br&gt;  //得到根句柄&lt;br&gt;  tvitem.hItem=(HTREEITEM)::SendMessage(hwnd, TVM_GETNEXTITEM,TVGN_ROOT, 0x0);&lt;br&gt;  ::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET, (long)tvitem.hItem);//选中状态&lt;br&gt;  &lt;br&gt;  while((long)tvitem.hItem)&lt;br&gt;  {&lt;br&gt;   //当此项目能展开时&lt;br&gt;   while(::SendMessage(hwnd, TVM_EXPAND,TVE_EXPAND, (long)tvitem.hItem))&lt;br&gt;   {&lt;br&gt;    //选择下一个可见项目&lt;br&gt;    tvitem.hItem=(HTREEITEM)::SendMessage(hwnd, &lt;br&gt;      TVM_GETNEXTITEM,TVGN_NEXTVISIBLE,&lt;br&gt;      (long)tvitem.hItem);&lt;/div&gt;
&lt;div&gt;    //选中状态&lt;br&gt;    ::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET, (long)tvitem.hItem);&lt;br&gt;    continue;&lt;br&gt;   }&lt;br&gt;   &lt;/div&gt;
&lt;div&gt;   //当不能再展开的时候，选择下一个可见项目&lt;br&gt;   tvitem.hItem=(HTREEITEM)::SendMessage(hwnd, &lt;br&gt;     TVM_GETNEXTITEM,TVGN_NEXTVISIBLE, &lt;br&gt;     (long)tvitem.hItem);&lt;/div&gt;
&lt;div&gt;   //选中状态&lt;br&gt;   ::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET, &lt;br&gt;      (long)tvitem.hItem);&lt;br&gt;   &lt;br&gt;  }&lt;br&gt; }&lt;br&gt; &lt;br&gt; //释放内存&lt;br&gt; CloseHandle(hwnd);&lt;br&gt; //顺序显示（选中）完毕&lt;/div&gt;
&lt;div&gt;三：TV_Demo_SeqShow的使用方法（图2）：&lt;/div&gt;
&lt;div&gt;图二&lt;/div&gt;
&lt;div&gt;用SPY++的[Find Window]功能获得目标TV的句柄； &lt;br&gt;将句柄值输入到TV_Demo_SeqShow中的[Tree-View Control''s Handle:]； &lt;br&gt;点击[GO!]； &lt;br&gt;　　如果你把[Windows 资源管理器]中的[文件夹]作为目标，那你可要作好心理准备了……如果实在忍受不了这种刺激，干脆把管理器关掉就可以了。&lt;/div&gt;
&lt;div&gt;第二部分：查找外部程序Tree-View中的项目&lt;/div&gt;
&lt;div&gt;一：程序说明：&lt;/div&gt;
&lt;div&gt;　　我们已经成功得对外部程序Tree-View中的项目进行了遍历，如果能在遍历的过程中读取每一个项目的名称，结合我们给定的项目名进行比较，那么查找某个项目的问题将变得易如反掌。由此可见：关键的问题是如何读取项目的名称。&lt;br&gt;　　读取项目的名称要发送TVM_GETITEM消息，由于该消息需要为LPARAM参数提供一个TV_ITEM结构的地址，在跨进程发送消息的前提下，为了使外部程序正常使用该内存地址，所以我们必须将TV_ITEM结构插入到目标进程的地址空间中去，代码如下： &lt;/div&gt;
&lt;div&gt;ptvitem=(TVITEM*)VirtualAllocEx(hProcess,NULL,sizeof(TVITEM),MEM_COMMIT,PAGE_READWRITE);//分配内存&lt;br&gt;WriteProcessMemory(hProcess,ptvitem,&amp;amp;tvitem,sizeof(TVITEM),NULL);//写入内存&lt;/div&gt;
&lt;div&gt;在写入内存之前，要将TV_ITEM结构配置好：     tvitem.mask=TVIF_TEXT;&lt;br&gt;    tvitem.cchTextMax=512;&lt;br&gt;    tvitem.pszText=pItem;&lt;/div&gt;
&lt;div&gt;mask要设置成TVIF_TEXT，因为我们需要的是pszText的值；cchTextMax可以设置得稍微大一些，cchTextMax=512即可；hItem的值用来指定究竟哪个项目来接收TVM_GETITEM消息，该值在遍历的过程中动态获得；重要的是用来存放项目名称的缓冲区地址，即pszText参数的设置：和TV_ITEM结构一样，也要把她插入到目标进程的地址空间中去： pItem=(char*)VirtualAllocEx(hProcess,NULL,16,MEM_COMMIT,PAGE_READWRITE);&lt;/div&gt;
&lt;div&gt;二：具体实践：&lt;br&gt;　　作为演示，下面的这段程序将在我们指定的Tree-View控件中查找我们需要的项目，在发现第一个部分匹配的项目后，程序将停止运行，不再进行查找操作。作为演示程序，程序并没有做速度上的优化，大家在具体应用的过程中可自行修改。程序找到目标后的效果图（图 三）： &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; /* Tree-View Control_Demo_SeqSearch 1.0 版&lt;br&gt; * 版权所有 (C) 2006 天津 赵春生&lt;br&gt; * 2006.08.28&lt;br&gt; * &lt;a href="http://timw.yeah.net/"&gt;http://timw.yeah.net&lt;/a&gt;&lt;br&gt; * &lt;a href="http://timw.126.com/"&gt;http://timw.126.com&lt;/a&gt;&lt;br&gt; * 本程序能按用户指定的项目名称顺序查找TV控件中的项目。&lt;br&gt; * 代码在Win2000P+SP4 + VC6+SP6测试通过。&lt;br&gt; */&lt;/div&gt;
&lt;div&gt; if(error==0)//如果在数据验证转换的过程中未出现错误（error==0时无错误）&lt;br&gt; {&lt;br&gt;  &lt;br&gt;  //下面为核心部分：按用户指定的项目名称顺序查找Tree-View控件中的Item.&lt;br&gt;  &lt;br&gt;  hwnd=HWND(dec_sum);//得到转换后的数据&lt;br&gt;  &lt;br&gt;  GetWindowThreadProcessId(hwnd, &amp;amp;PID);&lt;br&gt;  &lt;br&gt;  hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);&lt;br&gt;  if (!hProcess)&lt;br&gt;   MessageBox(&amp;quot;获取进程句柄操作失败！&amp;quot;,&amp;quot;错误！&amp;quot;);&lt;br&gt;  else&lt;br&gt;  {&lt;br&gt;   ptvitem=(TVITEM*)VirtualAllocEx(hProcess, &lt;br&gt;      NULL, &lt;br&gt;      sizeof(TVITEM), &lt;br&gt;      MEM_COMMIT, &lt;br&gt;      PAGE_READWRITE);&lt;br&gt;   pItem=(char*)VirtualAllocEx(hProcess, &lt;br&gt;      NULL, &lt;br&gt;      16, &lt;br&gt;      MEM_COMMIT, &lt;br&gt;      PAGE_READWRITE);&lt;br&gt;   &lt;br&gt;   if (!ptvitem)&lt;br&gt;    MessageBox(&amp;quot;无法分配内存！&amp;quot;,&amp;quot;错误！&amp;quot;);&lt;br&gt;   else&lt;br&gt;   {&lt;br&gt;    MessageBox(&amp;quot;本演示程序将按用户指定的项目名称顺序查找。&amp;quot;,&amp;quot;提示&amp;quot;);&lt;br&gt;    &lt;br&gt;    tvitem.mask=TVIF_TEXT;&lt;br&gt;    tvitem.cchTextMax=512;&lt;br&gt;    tvitem.pszText=pItem;&lt;br&gt;    &lt;br&gt;    //得到根句柄&lt;br&gt;    tvitem.hItem=(HTREEITEM)::SendMessage(hwnd, &lt;br&gt;        TVM_GETNEXTITEM,&lt;br&gt;        TVGN_ROOT, &lt;br&gt;        0x0);&lt;/div&gt;
&lt;div&gt;    //选中状态&lt;br&gt;    ::SendMessage(hwnd, &lt;br&gt;       TVM_SELECTITEM,&lt;br&gt;       TVGN_CARET, &lt;br&gt;       (long)tvitem.hItem);&lt;br&gt;    &lt;br&gt;    //将设置好的结构插入目标进程&lt;br&gt;    WriteProcessMemory(hProcess, &lt;br&gt;        ptvitem, &lt;br&gt;        &amp;amp;tvitem,  &lt;br&gt;        sizeof(TVITEM), NULL);&lt;/div&gt;
&lt;div&gt;    //发送TVM_GETITEM消息&lt;br&gt;    ::SendMessage(hwnd, &lt;br&gt;       TVM_GETITEM,&lt;br&gt;       0, &lt;br&gt;       (LPARAM)ptvitem);&lt;/div&gt;
&lt;div&gt;    //获取pszText&lt;br&gt;    ReadProcessMemory(hProcess, pItem, ItemBuf, 512, NULL);&lt;/div&gt;
&lt;div&gt;    //MessageBox(ItemBuf,&amp;quot;ITEM TEXT&amp;quot;);&lt;br&gt;    if( strnicmp( ItemBuf,&lt;br&gt;       str_item_text,&lt;br&gt;       strlen(str_item_text) ) == 0)&lt;br&gt;    {&lt;br&gt;     MessageBox(&amp;quot;已经找到！&amp;quot;,&amp;quot;恭喜&amp;quot;);&lt;br&gt;     Bingo=1;&lt;br&gt;     //如果根就是我们要找的目标，那么程序执行到这里就可以结束了。&lt;br&gt;     tvitem.hItem=(HTREEITEM)0x0;&lt;br&gt;    }&lt;br&gt;    &lt;br&gt;    while((long)tvitem.hItem)&lt;br&gt;    {&lt;br&gt;     //当此项目能展开时&lt;br&gt;     while(::SendMessage(hwnd, &lt;br&gt;         TVM_EXPAND,&lt;br&gt;         TVE_EXPAND, &lt;br&gt;         (long)tvitem.hItem))&lt;br&gt;     {&lt;/div&gt;
&lt;div&gt;      //选择下一个可见项目&lt;br&gt;      tvitem.hItem=(HTREEITEM)::SendMessage(hwnd, &lt;br&gt;        TVM_GETNEXTITEM,TVGN_NEXTVISIBLE, &lt;br&gt;        (long)tvitem.hItem);&lt;br&gt;      //选中状态&lt;br&gt;      ::SendMessage(hwnd, &lt;br&gt;       TVM_SELECTITEM,TVGN_CARET, &lt;br&gt;       (long)tvitem.hItem);&lt;/div&gt;
&lt;div&gt;      //将设置好的结构插入目标进程&lt;br&gt;      WriteProcessMemory(hProcess, &lt;br&gt;        ptvitem, &lt;br&gt;        &amp;amp;tvitem, &lt;br&gt;        sizeof(TVITEM), &lt;br&gt;        NULL);&lt;br&gt;      //发送TVM_GETITEM消息&lt;br&gt;      ::SendMessage(hwnd, &lt;br&gt;       TVM_GETITEM,&lt;br&gt;       0, &lt;br&gt;       (LPARAM)ptvitem);&lt;/div&gt;
&lt;div&gt;      //获取pszText&lt;br&gt;      ReadProcessMemory(hProcess, &lt;br&gt;        pItem, &lt;br&gt;        ItemBuf, &lt;br&gt;        512, &lt;br&gt;        NULL);&lt;/div&gt;
&lt;div&gt;      //MessageBox(ItemBuf,&amp;quot;ITEM TEXT&amp;quot;);&lt;br&gt;      if( strnicmp( ItemBuf,&lt;br&gt;         str_item_text,&lt;br&gt;         strlen(str_item_text) ) == 0)&lt;br&gt;      {&lt;br&gt;       MessageBox(&amp;quot;已经找到！&amp;quot;,&amp;quot;恭喜&amp;quot;);&lt;br&gt;       Bingo=1;&lt;/div&gt;
&lt;div&gt;       //如果发现我们要找的目标，那么程序执行到这里就可以结束了。&lt;br&gt;       tvitem.hItem=(HTREEITEM)0x0;&lt;br&gt;       break;&lt;br&gt;      }&lt;br&gt;      continue;&lt;br&gt;     }&lt;br&gt;     &lt;br&gt;     if(Bingo!=1)&lt;br&gt;     {&lt;br&gt;      //当不能再展开的时候，选择下一个可见项目&lt;br&gt;      tvitem.hItem=(HTREEITEM)::SendMessage(hwnd, &lt;br&gt;         TVM_GETNEXTITEM,TVGN_NEXTVISIBLE, &lt;br&gt;         (long)tvitem.hItem);&lt;/div&gt;
&lt;div&gt;      //选中状态&lt;br&gt;      ::SendMessage(hwnd, &lt;br&gt;         TVM_SELECTITEM,&lt;br&gt;         TVGN_CARET, &lt;br&gt;         (long)tvitem.hItem);&lt;/div&gt;
&lt;div&gt;      //将设置好的结构插入目标进程&lt;br&gt;      WriteProcessMemory(hProcess, &lt;br&gt;           ptvitem, &lt;br&gt;           &amp;amp;tvitem, &lt;br&gt;           sizeof(TVITEM), &lt;br&gt;           NULL);&lt;/div&gt;
&lt;div&gt;      //发送TVM_GETITEM消息&lt;br&gt;      ::SendMessage(hwnd, &lt;br&gt;         TVM_GETITEM,&lt;br&gt;         0, &lt;br&gt;         (LPARAM)ptvitem);&lt;br&gt;         &lt;br&gt;      ReadProcessMemory(hProcess, &lt;br&gt;          pItem, &lt;br&gt;          ItemBuf, &lt;br&gt;          512, &lt;br&gt;          NULL);//获取pszText&lt;br&gt;          &lt;br&gt;      //MessageBox(ItemBuf,&amp;quot;ITEM TEXT&amp;quot;);&lt;br&gt;      if( strnicmp( ItemBuf,&lt;br&gt;          str_item_text,&lt;br&gt;          strlen(str_item_text) ) == 0)&lt;br&gt;      {&lt;br&gt;       MessageBox(&amp;quot;已经找到！&amp;quot;,&amp;quot;恭喜&amp;quot;);&lt;br&gt;       Bingo=1;&lt;/div&gt;
&lt;div&gt;       //如果发现我们要找的目标，那么程序执行到这里就可以结束了。&lt;br&gt;       tvitem.hItem=(HTREEITEM)0x0;&lt;br&gt;       break;&lt;br&gt;      }&lt;br&gt;     }&lt;br&gt;     &lt;br&gt;    }&lt;br&gt;   }&lt;br&gt;  }&lt;br&gt; }&lt;br&gt; &lt;br&gt; //释放内存&lt;br&gt; CloseHandle(hwnd);&lt;br&gt; CloseHandle(hProcess);&lt;br&gt; VirtualFreeEx(hProcess, ptvitem, 0, MEM_RELEASE);&lt;br&gt; //顺序查找完毕&lt;/div&gt;
&lt;div&gt;结束语&lt;br&gt;代码写得不够幽雅，大家见笑了。在此之前，类似的拙文我已经写了四篇，希望大家看完后能举一反三。谢谢。&lt;/div&gt;
&lt;div&gt;&lt;br&gt; &lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+%e9%81%8d%e5%8e%86%e5%92%8c%e6%9f%a5%e6%89%be%e5%a4%96%e9%83%a8%e7%a8%8b%e5%ba%8f+Tree-View+%e4%b8%ad%e7%9a%84%e9%a1%b9%e7%9b%ae(%e8%bd%ac)&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1012.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1012.entry</guid><pubDate>Mon, 23 Jul 2007 06:34:31 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1012/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1012.entry#comment</wfw:comment><dcterms:modified>2007-07-23T06:34:31Z</dcterms:modified></item><item><title>如何查找项目在树控件通过其标签(转)</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1011.entry</link><description>&lt;div&gt;如何查找项目在树控件通过其标签(转)&lt;br&gt;来自:http://support.microsoft.com/kb/155895/zh-cn&lt;br&gt;如何查找项目在树控件通过其标签&lt;br&gt;察看本文应用于的产品&lt;br&gt;注意：这篇文章是由无人工介入的自动的机器翻译系统翻译完成。这些文章是微软为不懂英语的用户提供的, 以使他们能够理解这些文章的内容。微软不保证机器翻译的正确度，也不对由于内容的误译或者客户对它的使用所引起的任何直接的, 或间接的可能的问题负责。&lt;br&gt;文章编号 : 155895 &lt;br&gt;最后修改 : 2003年12月10日 &lt;br&gt;修订 : 2.0 &lt;br&gt;本页&lt;/div&gt;
&lt;div&gt;概要&lt;/div&gt;
&lt;div&gt;更多信息&lt;/div&gt;
&lt;div&gt;示例代码&lt;br&gt;概要&lt;br&gt;&amp;quot; 树视图 &amp;quot; 公共控件没有任何内置方法用于搜索整个树, 或用于选择给定特定项标签时树中包含一个项。 本文提供代码返回给定特定标签以搜索时树中的任何项目位置。 &lt;/div&gt;
&lt;div&gt;GetItemByName() 函数采用树控件, HTREEITEM, 它指向该树以开始搜索和对要搜索字符串中项的窗口句柄。 &lt;br&gt;回到顶端&lt;/div&gt;
&lt;div&gt;更多信息&lt;br&gt;示例代码&lt;br&gt;#include &amp;lt;windows.h&amp;gt;&lt;br&gt;#include &amp;lt;commctrl.h&amp;gt;&lt;/div&gt;
&lt;div&gt;// Note: If you have items with more than 50 characters&lt;br&gt;// of text, you'll need to increase this value.&lt;br&gt;#define MAXTEXTLEN 50&lt;/div&gt;
&lt;div&gt;HTREEITEM GetItemByName(HWND hWnd, HTREEITEM hItem,&lt;br&gt;                        LPCTSTR szItemName)&lt;br&gt;{&lt;br&gt;    // If hItem is NULL, start search from root item.&lt;br&gt;    if (hItem == NULL)&lt;br&gt;        hItem = (HTREEITEM)SendMessage(hWnd, TVM_GETNEXTITEM,&lt;br&gt;                                       TVGN_ROOT, 0);&lt;br&gt;    while (hItem != NULL)&lt;br&gt;    {&lt;br&gt;        char szBuffer[MAXTEXTLEN+1];&lt;br&gt;        TV_ITEM item;&lt;/div&gt;
&lt;div&gt;        item.hItem = hItem;&lt;br&gt;        item.mask = TVIF_TEXT | TVIF_CHILDREN;&lt;br&gt;        item.pszText = szBuffer;&lt;br&gt;        item.cchTextMax = MAXTEXTLEN;&lt;br&gt;        SendMessage(hWnd, TVM_GETITEM, 0, (LPARAM)&amp;amp;item);&lt;/div&gt;
&lt;div&gt;        // Did we find it?&lt;br&gt;        if (lstrcmp(szBuffer, szItemName) == 0)&lt;br&gt;            return hItem;&lt;/div&gt;
&lt;div&gt;        // Check whether we have child items.&lt;br&gt;        if (item.cChildren)&lt;br&gt;        {&lt;br&gt;            // Recursively traverse child items.&lt;br&gt;            HTREEITEM hItemFound, hItemChild;&lt;/div&gt;
&lt;div&gt;            hItemChild = (HTREEITEM)SendMessage(hWnd, TVM_GETNEXTITEM,&lt;br&gt;                                                TVGN_CHILD, (LPARAM)hItem);&lt;br&gt;            hItemFound = GetItemByName(hWnd, hItemChild, szItemName);&lt;/div&gt;
&lt;div&gt;            // Did we find it?&lt;br&gt;            if (hItemFound != NULL)&lt;br&gt;                return hItemFound;&lt;br&gt;        }&lt;/div&gt;
&lt;div&gt;        // Go to next sibling item.&lt;br&gt;        hItem = (HTREEITEM)SendMessage(hWnd, TVM_GETNEXTITEM,&lt;br&gt;                                       TVGN_NEXT, (LPARAM)hItem);&lt;br&gt;    }&lt;/div&gt;
&lt;div&gt;    // Not found.&lt;br&gt;    return NULL;&lt;br&gt;}&lt;br&gt;    &lt;br&gt;例如, 以搜索整个树对单词 &amp;quot; JeffSmith &amp;quot; 和然后突出显示该单词, 您可以使用以下代码： &lt;/div&gt;
&lt;div&gt;使用 Windows SDK：     HTREEITEM hItem;&lt;br&gt;    hItem = GetItemByName(hWndTreeCtrl, NULL, &amp;quot;Jeff&amp;quot;);&lt;br&gt;    if (hItem != NULL)&lt;br&gt;        SendMessage(hWndTreeCtrl, TVM_SELECTITEM, TVGN_CARET,&lt;br&gt;                    (LPARAM)hItem);&lt;br&gt;    &lt;br&gt;使用 MFC：     HTREEITEM hItem = GetItemByName(m_TreeCtrl.GetSafeHwnd(),&lt;br&gt;                                    NULL, &amp;quot;Jeff&amp;quot;);&lt;br&gt;    if (hItem != NULL)&lt;br&gt;        m_TreeCtrl.SelectItem(hItem);&lt;br&gt;    &lt;br&gt;回到顶端&lt;/div&gt;
&lt;div&gt;&lt;br&gt;--------------------------------------------------------------------------------&lt;/div&gt;
&lt;div&gt;这篇文章中的信息适用于:&lt;br&gt;• Microsoft Visual C++ 2.2 &lt;br&gt;• Microsoft Visual C++ 4.0 Standard Edition &lt;br&gt;• Microsoft Visual C++ 4.1 Subscription &lt;br&gt;• Microsoft Visual C++ 4.2 Enterprise Edition &lt;br&gt;• Microsoft Visual C++ 4.2 Professional Edition &lt;/div&gt;
&lt;div&gt;回到顶端&lt;/div&gt;
&lt;div&gt;关键字：  kbcode KB155895 KbMtzh kbmt &lt;/div&gt;
&lt;div&gt;回到顶端&lt;/div&gt;
&lt;div&gt;Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性，不作任何声明。 所有该等文件及有关图形均&amp;quot;依样&amp;quot;提供，而不带任何性质的保证。Microsoft和/或其各供应商特此声明，对所有与该等信息有关的保证和条件不负任何责任，该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下，在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中，Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、 &lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-8189920746979949719&amp;page=RSS%3a+%e5%a6%82%e4%bd%95%e6%9f%a5%e6%89%be%e9%a1%b9%e7%9b%ae%e5%9c%a8%e6%a0%91%e6%8e%a7%e4%bb%b6%e9%80%9a%e8%bf%87%e5%85%b6%e6%a0%87%e7%ad%be(%e8%bd%ac)&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=flipcode.spaces.live.com&amp;amp;GT1=flipcode"&gt;</description><comments>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1011.entry#comment</comments><guid isPermaLink="true">http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1011.entry</guid><pubDate>Mon, 23 Jul 2007 06:32:26 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1011/comments/feed.rss</wfw:commentRss><wfw:comment>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1011.entry#comment</wfw:comment><dcterms:modified>2007-07-23T06:32:26Z</dcterms:modified></item><item><title>vc++的LNK2005错误（转）</title><link>http://flipcode.spaces.live.com/Blog/cns!8E578E7901A88369!1008.entry</link><description>&lt;div&gt;[转者: 之前转过另一篇也是这种错误的不错文章，可以找来看看。]&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; VC++的LNK2005错误 (转)&lt;br&gt;摘自:http://blog.csdn.net/vcleaner/archive/2005/02/01/276278.aspx&lt;br&gt;       编程中经常能遇到LNK2005错误——重复定义错误，其实LNK2005错误并不是一个很难解决的错误。弄清楚它形成的原因，就可以轻松解决它了。&lt;/div&gt;
