﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-MDA之路</title><link>http://www.blogjava.net/wxb_nudt/</link><description>MDA,UML,XML,Eclipse及Java相关的Blog</description><language>zh-cn</language><lastBuildDate>Mon, 20 Apr 2026 21:04:42 GMT</lastBuildDate><pubDate>Mon, 20 Apr 2026 21:04:42 GMT</pubDate><ttl>60</ttl><item><title>妈妈生日快乐！</title><link>http://www.blogjava.net/wxb_nudt/archive/2010/05/20/321496.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Thu, 20 May 2010 12:03:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2010/05/20/321496.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/321496.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2010/05/20/321496.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/321496.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/321496.html</trackback:ping><description><![CDATA[农历四月初七，是我妈妈的生日，祝妈妈生日快乐！
<img src ="http://www.blogjava.net/wxb_nudt/aggbug/321496.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wxb_nudt/" target="_blank">wxb_nudt</a> 2010-05-20 20:03 <a href="http://www.blogjava.net/wxb_nudt/archive/2010/05/20/321496.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tuxedo安装,license,例子和远程客户端配置</title><link>http://www.blogjava.net/wxb_nudt/archive/2009/03/14/259772.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Sat, 14 Mar 2009 15:25:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2009/03/14/259772.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/259772.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2009/03/14/259772.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/259772.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/259772.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 摘要：本文总结了Tuxedo的安装、license、例子运行和远程客户端配置四个主要问题，给出了一篇真正可用的Tuxedo入门教程。<br><br>Tuxedo是一个很好的交易中间件，包含消息中间件等功能，历史悠久，功能强大，是由BEA开发的，不过现在属于Oracle了。网上的Tuxedo入门教程千千万万，几乎没有一个可用的。尤其是在licsence和远程客户端配置这两个问题上，都没有交代清楚。很符合中国的IT教程特色：“懂得人看得懂，但是并没有更懂；不懂的人更加不懂了！”。<br><br>&nbsp;&nbsp;<a href='http://www.blogjava.net/wxb_nudt/archive/2009/03/14/259772.html'>阅读全文</a><img src ="http://www.blogjava.net/wxb_nudt/aggbug/259772.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wxb_nudt/" target="_blank">wxb_nudt</a> 2009-03-14 23:25 <a href="http://www.blogjava.net/wxb_nudt/archive/2009/03/14/259772.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>博客搬家了！关注的朋友可以去新博客看看！</title><link>http://www.blogjava.net/wxb_nudt/archive/2008/09/20/230161.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Sat, 20 Sep 2008 09:25:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2008/09/20/230161.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/230161.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2008/09/20/230161.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/230161.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/230161.html</trackback:ping><description><![CDATA[新博客在CSDN，地址是<font style="background-color: #b7e8bd">http://blog.csdn.net/wxb_nudt</font><br />
新博客的第一篇博文是：&nbsp;<a href="http://blog.csdn.net/wxb_nudt/archive/2008/09/16/2938242.aspx">C++中的数据类型转换方法总结</a><br />
以后两个博客同时更新吧，主要精力在csdn的博客，因为最近java用得很少，在这里似乎不合题。<br />
<img src ="http://www.blogjava.net/wxb_nudt/aggbug/230161.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wxb_nudt/" target="_blank">wxb_nudt</a> 2008-09-20 17:25 <a href="http://www.blogjava.net/wxb_nudt/archive/2008/09/20/230161.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中的XML配置文件编程经验</title><link>http://www.blogjava.net/wxb_nudt/archive/2008/05/27/203317.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Tue, 27 May 2008 11:40:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2008/05/27/203317.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/203317.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2008/05/27/203317.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/203317.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/203317.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: C++中并没有操作XML文件的标准库，因此大家需要使用各自熟悉的XML库来解决XML文件的读取与写入。XML的一个重要用途是作为程序的配置文件，存储程序运行相关的各种数据。本文总结了使用libxml2库来对XML配置文件进行编程的一些经验。最后提供了一个封装好的类CXMLConfig，并详细说明了该类的功能、使用方法和注意事项。&nbsp;&nbsp;<a href='http://www.blogjava.net/wxb_nudt/archive/2008/05/27/203317.html'>阅读全文</a><img src ="http://www.blogjava.net/wxb_nudt/aggbug/203317.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wxb_nudt/" target="_blank">wxb_nudt</a> 2008-05-27 19:40 <a href="http://www.blogjava.net/wxb_nudt/archive/2008/05/27/203317.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>m文件转换为C/C++文件的编译、绘图、参数、打包问题总结</title><link>http://www.blogjava.net/wxb_nudt/archive/2008/01/28/178246.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Mon, 28 Jan 2008 12:16:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2008/01/28/178246.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/178246.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2008/01/28/178246.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/178246.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/178246.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在工程计算相关项目中，常常利用Matlab来完成计算、算法、绘图等功能。使用Matlab来完成这些功能非常简单，Matlab提供的m编程语言功能强大，代码量少。为了在自己的C/C++项目中加入这些功能，需要一系列繁琐的过程，令很多人望之却步。主要的困难在于：<br><br>l         如何从m文件生成VC可用的C/C++代码；<br><br>l         如何设置编译参数，在VC中编译这些代码；<br><br>l         如何在C/C++语言中设置输入输出参数，使之与M代码生成的C++代码一同运行；<br><br>l         如何制作包含matlab运行时库的安装程序。<br><br>&nbsp;&nbsp;<a href='http://www.blogjava.net/wxb_nudt/archive/2008/01/28/178246.html'>阅读全文</a><img src ="http://www.blogjava.net/wxb_nudt/aggbug/178246.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wxb_nudt/" target="_blank">wxb_nudt</a> 2008-01-28 20:16 <a href="http://www.blogjava.net/wxb_nudt/archive/2008/01/28/178246.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++的XML编程经验――LIBXML2库使用指南</title><link>http://www.blogjava.net/wxb_nudt/archive/2007/11/18/161340.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Sun, 18 Nov 2007 01:42:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2007/11/18/161340.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/161340.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2007/11/18/161340.html#Feedback</comments><slash:comments>49</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/161340.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/161340.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 写这篇文章的原因有如下几点：1)C++标准库中没有操作XML的方法，用C++操作XML文件必须熟悉一种函数库，LIBXML2是其中一种很优秀的XML库，而且它同时支持多种编程语言；2)LIBXML2库的Tutorial写得不太好，尤其是编码转换的部分，不适用于中文编码的转换；3)网上的大多数关于Libxml2的介绍仅仅是翻译了自带的资料，没有详细介绍如何在windows平台下进行编程，更很少提到如何解决中文问题。&nbsp;&nbsp;<a href='http://www.blogjava.net/wxb_nudt/archive/2007/11/18/161340.html'>阅读全文</a><img src ="http://www.blogjava.net/wxb_nudt/aggbug/161340.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wxb_nudt/" target="_blank">wxb_nudt</a> 2007-11-18 09:42 <a href="http://www.blogjava.net/wxb_nudt/archive/2007/11/18/161340.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Socket编程指南及示例程序</title><link>http://www.blogjava.net/wxb_nudt/archive/2007/11/01/157623.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Thu, 01 Nov 2007 15:20:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2007/11/01/157623.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/157623.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2007/11/01/157623.html#Feedback</comments><slash:comments>44</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/157623.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/157623.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在一些常用的编程技术中，Socket网络编程可以说是最简单的一种。而且Socket编程需要的基础知识很少，适合初学者学习网络编程。目前支持网络传输的技术、语言和工具繁多，但是大部分都是基于Socket开发的，虽说这些“高级”的网络技术屏蔽了大部分底层实现，号称能极大程度的简化开发，而事实上如果你没有一点Socket基础，要理解和应用这些技术还是很困难的，而且会让你成为“半瓢水”。<br>例子代码就在我的博客中，包括六个UDP和TCP发送接受的cpp文件，一个基于MFC的局域网聊天小工具工程，和此小工具的所有运行时库、资源和执行程序。&nbsp;&nbsp;<a href='http://www.blogjava.net/wxb_nudt/archive/2007/11/01/157623.html'>阅读全文</a><img src ="http://www.blogjava.net/wxb_nudt/aggbug/157623.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wxb_nudt/" target="_blank">wxb_nudt</a> 2007-11-01 23:20 <a href="http://www.blogjava.net/wxb_nudt/archive/2007/11/01/157623.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>纸黄金均价管理小软件—黄金秘书</title><link>http://www.blogjava.net/wxb_nudt/archive/2007/10/20/154584.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Sat, 20 Oct 2007 15:13:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2007/10/20/154584.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/154584.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2007/10/20/154584.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/154584.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/154584.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 最近炒纸黄金，用的是工行的网上银行。但是不久就发现工行没有提供相应的均价管理工具，自己的均价和账面盈亏都得用笔记本写下来然后用计算器算。自己的历史盈亏等等信息也要用笔记本记下来。这样在原始社会混了几天后，终于忍不住写了一个小软件来管理纸黄金的均价、仓位、资金、历史盈亏、账面盈亏等信息，就叫做黄金秘书。<br>想试用这个小软件的，可以直接在我的博客下载这两个压缩包，解压后安装即可，安装和试用说明见下节：<br>&nbsp;&nbsp;<a href='http://www.blogjava.net/wxb_nudt/archive/2007/10/20/154584.html'>阅读全文</a><img src ="http://www.blogjava.net/wxb_nudt/aggbug/154584.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wxb_nudt/" target="_blank">wxb_nudt</a> 2007-10-20 23:13 <a href="http://www.blogjava.net/wxb_nudt/archive/2007/10/20/154584.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DLL编写教程</title><link>http://www.blogjava.net/wxb_nudt/archive/2007/09/11/144371.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Tue, 11 Sep 2007 14:13:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2007/09/11/144371.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/144371.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2007/09/11/144371.html#Feedback</comments><slash:comments>113</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/144371.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/144371.html</trackback:ping><description><![CDATA[<p>&nbsp; </p>
<p style="text-align: center" align="center"><span style="font-size: 16pt">DLL</span><span style="font-size: 16pt; font-family: 宋体">编写教程</span></p>
<p><span style="font-family: 宋体">半年不能上网，最近网络终于通了，终于可以更新博客了，写点什么呢？决定最近写一个编程技术系列，其内容是一些通用的编程技术。例如</span>DLL<span style="font-family: 宋体">，</span>COM<span style="font-family: 宋体">，</span>Socket<span style="font-family: 宋体">，多线程等等。这些技术的特点就是使用广泛，但是误解很多；网上教程很多，但是几乎没有什么优质良品。我以近几个月来的编程经验发现，很有必要好好的总结一下这些编程技术了。一来对自己是总结提高，二来可以方便光顾我博客的朋友。</span></p>
<p><span style="font-family: 宋体">好了，废话少说，言归正传。第一篇就是《</span>DLL<span style="font-family: 宋体">编写教程》，为什么起这么土的名字呢？为什么不叫《轻轻松松写</span>DLL<span style="font-family: 宋体">》或者《</span>DLL<span style="font-family: 宋体">一日通》呢？或者更</span>nb<span style="font-family: 宋体">的《深入简出</span>DLL<span style="font-family: 宋体">》呢？呵呵，常常上网搜索资料的弟兄自然知道。</span></p>
<p><span style="font-family: 宋体">本文对通用的</span>DLL<span style="font-family: 宋体">技术做了一个总结，并提供了源代码打包下载，下载地址为：</span></p>
<p><a href="http://www.blogjava.net/Files/wxb_nudt/DLL_SRC.rar">http://www.blogjava.net/Files/wxb_nudt/DLL_SRC.rar</a></p>
<h1>DLL<span style="font-family: 宋体">的优点</span></h1>
<p><span style="font-family: 宋体">简单的说，</span>dll<span style="font-family: 宋体">有以下几个优点：</span></p>
<p style="margin-left: 18pt; text-indent: -18pt; tab-stops: list 18.0pt">1)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">节省内存。同一个软件模块，若是以源代码的形式重用，则会被编译到不同的可执行程序中，同时运行这些</span>exe<span style="font-family: 宋体">时这些模块的二进制码会被重复加载到内存中。如果使用</span>dll<span style="font-family: 宋体">，则只在内存中加载一次，所有使用该</span>dll<span style="font-family: 宋体">的进程会共享此块内存（当然，像</span>dll<span style="font-family: 宋体">中的全局变量这种东西是会被每个进程复制一份的）。</span></p>
<p style="margin-left: 18pt; text-indent: -18pt; tab-stops: list 18.0pt">2)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">不需编译的软件系统升级，若一个软件系统使用了</span>dll<span style="font-family: 宋体">，则该</span>dll<span style="font-family: 宋体">被改变（函数名不变）时，系统升级只需要更换此</span>dll<span style="font-family: 宋体">即可，不需要重新编译整个系统。事实上，很多软件都是以这种方式升级的。例如我们经常玩的星际、魔兽等游戏也是这样进行版本升级的。</span></p>
<p style="margin-left: 18pt; text-indent: -18pt; tab-stops: list 18.0pt">3)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Dll<span style="font-family: 宋体">库可以供多种编程语言使用，例如用</span>c<span style="font-family: 宋体">编写的</span>dll<span style="font-family: 宋体">可以在</span>vb<span style="font-family: 宋体">中调用。这一点上</span>DLL<span style="font-family: 宋体">还做得很不够，因此在</span>dll<span style="font-family: 宋体">的基础上发明了</span>COM<span style="font-family: 宋体">技术，更好的解决了一系列问题。</span></p>
<h1><span style="font-family: 宋体">最简单的</span>dll</h1>
<p><span style="font-family: 宋体">开始写</span>dll<span style="font-family: 宋体">之前，你需要一个</span>c/c++<span style="font-family: 宋体">编译器和链接器，并关闭你的</span>IDE<span style="font-family: 宋体">。是的，把你的</span>VC<span style="font-family: 宋体">和</span>C++ BUILDER<span style="font-family: 宋体">之类的东东都关掉，并打开你以往只用来记电话的记事本程序。不这样做的话，你可能一辈子也不明白</span>dll<span style="font-family: 宋体">的真谛。我使用了</span>VC<span style="font-family: 宋体">自带的</span>cl<span style="font-family: 宋体">编译器和</span>link<span style="font-family: 宋体">链接器，它们一般都在</span>vc<span style="font-family: 宋体">的</span>bin<span style="font-family: 宋体">目录下。（若你没有在安装</span>vc<span style="font-family: 宋体">的时候选择注册环境变量，那么就立刻将它们的路径加入</span>path<span style="font-family: 宋体">吧）如果你还是因为离开了</span>IDE<span style="font-family: 宋体">而害怕到哭泣的话，你可以关闭这个页面并继续去看《</span>VC++<span style="font-family: 宋体">技术内幕》之类无聊的书了。</span></p>
<p><span style="font-family: 宋体">最简单的</span>dll<span style="font-family: 宋体">并不比</span>c<span style="font-family: 宋体">的</span>helloworld<span style="font-family: 宋体">难，只要一个</span>DllMain<span style="font-family: 宋体">函数即可，包含</span>objbase.h<span style="font-family: 宋体">头文件（支持</span>COM<span style="font-family: 宋体">技术的一个头文件）。若你觉得这个头文件名字难记，那么用</span>windows.H<span style="font-family: 宋体">也可以。源代码如下：</span>dll_nolib.cpp</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>#include &lt;objbase.h&gt;</p>
<p>#include &lt;iostream.h&gt;</p>
<p>BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved) </p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; HANDLE g_hModule;</p>
<p>&nbsp;&nbsp;&nbsp; switch(dwReason)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp; case DLL_PROCESS_ATTACH:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;"Dll is attached!"&lt;&lt;endl;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g_hModule = (HINSTANCE)hModule;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</p>
<p>&nbsp;&nbsp;&nbsp; case DLL_PROCESS_DETACH:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;"Dll is detached!"&lt;&lt;endl;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g_hModule=NULL;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; return true;</p>
<p>}</p>
</div>
<p><span style="font-family: 宋体">其中</span>DllMain<span style="font-family: 宋体">是每个</span>dll<span style="font-family: 宋体">的入口函数，如同</span>c<span style="font-family: 宋体">的</span>main<span style="font-family: 宋体">函数一样。</span>DllMain<span style="font-family: 宋体">带有三个参数，</span>hModule<span style="font-family: 宋体">表示本</span>dll<span style="font-family: 宋体">的实例句柄（听不懂就不理它，写过</span>windows<span style="font-family: 宋体">程序的自然懂），</span>dwReason<span style="font-family: 宋体">表示</span>dll<span style="font-family: 宋体">当前所处的状态，例如</span>DLL_PROCESS_ATTACH<span style="font-family: 宋体">表示</span>dll<span style="font-family: 宋体">刚刚被加载到一个进程中，</span>DLL_PROCESS_DETACH<span style="font-family: 宋体">表示</span>dll<span style="font-family: 宋体">刚刚从一个进程中卸载。当然还有表示加载到线程中和从线程中卸载的状态，这里省略。最后一个参数是一个保留参数（目前和</span>dll<span style="font-family: 宋体">的一些状态相关，但是很少使用）。</span></p>
<p><span style="font-family: 宋体">从上面的程序可以看出，当</span>dll<span style="font-family: 宋体">被加载到一个进程中时，</span>dll<span style="font-family: 宋体">打印</span>"Dll is attached!"<span style="font-family: 宋体">语句；当</span>dll<span style="font-family: 宋体">从进程中卸载时，打印</span>"Dll is detached!"<span style="font-family: 宋体">语句。</span></p>
<p><span style="font-family: 宋体">编译</span>dll<span style="font-family: 宋体">需要以下两条命令：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>cl /c dll_nolib.cpp</p>
</div>
<p><span style="font-family: 宋体">这条命令会将</span>cpp<span style="font-family: 宋体">编译为</span>obj<span style="font-family: 宋体">文件，若不使用</span>/c<span style="font-family: 宋体">参数则</span>cl<span style="font-family: 宋体">还会试图继续将</span>obj<span style="font-family: 宋体">链接为</span>exe<span style="font-family: 宋体">，但是这里是一个</span>dll<span style="font-family: 宋体">，没有</span>main<span style="font-family: 宋体">函数，因此会报错。不要紧，继续使用链接命令。</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>Link /dll dll_nolib.obj</p>
</div>
<p><span style="font-family: 宋体">这条命令会生成</span>dll_nolib.dll<span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">注意，因为编译命令比较简单，所以本文不讨论</span>nmake<span style="font-family: 宋体">，有兴趣的可以使用</span>nmake<span style="font-family: 宋体">，或者写个</span>bat<span style="font-family: 宋体">批处理来编译链接</span>dll<span style="font-family: 宋体">。</span></p>
<h1><span style="font-family: 宋体">加载</span>DLL<span style="font-family: 宋体">（显式调用）</span></h1>
<p><span style="font-family: 宋体">使用</span>dll<span style="font-family: 宋体">大体上有两种方式，显式调用和隐式调用。这里首先介绍显式调用。编写一个客户端程序：</span>dll_nolib_client.cpp</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>#include &lt;windows.h&gt;</p>
<p>#include &lt;iostream.h&gt;</p>
<p>int main(void)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; //<span style="font-family: 宋体">加载我们的</span>dll</p>
<p>&nbsp;&nbsp;&nbsp; HINSTANCE hinst=::LoadLibrary("dll_nolib.dll");&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; if (NULL != hinst)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;"dll loaded!"&lt;&lt;endl;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; return 0;</p>
<p>}</p>
</div>
<p><span style="font-family: 宋体">注意，调用</span>dll<span style="font-family: 宋体">使用</span>LoadLibrary<span style="font-family: 宋体">函数，它的参数就是</span>dll<span style="font-family: 宋体">的路径和名称，返回值是</span>dll<span style="font-family: 宋体">的句柄。</span> <span style="font-family: 宋体">使用如下命令编译链接客户端：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>Cl dll_nolib_client.cpp</p>
</div>
<p><span style="font-family: 宋体">并执行</span>dll_nolib_client.exe<span style="font-family: 宋体">，得到如下结果：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>Dll is attached!</p>
<p>dll loaded!</p>
<p>Dll is detached!</p>
</div>
<p><span style="font-family: 宋体">以上结果表明</span>dll<span style="font-family: 宋体">已经被客户端加载过。但是这样仅仅能够将</span>dll<span style="font-family: 宋体">加载到内存，不能找到</span>dll<span style="font-family: 宋体">中的函数。</span></p>
<h1><span style="font-family: 宋体">使用</span>dumpbin<span style="font-family: 宋体">命令查看</span>DLL<span style="font-family: 宋体">中的函数</span></h1>
<p>Dumpbin<span style="font-family: 宋体">命令可以查看一个</span>dll<span style="font-family: 宋体">中的输出函数符号名，键入如下命令：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>Dumpbin &#8211;exports dll_nolib.dll</p>
</div>
<p><span style="font-family: 宋体">通过查看，发现</span>dll_nolib.dll<span style="font-family: 宋体">并没有输出任何函数。</span></p>
<h1><span style="font-family: 宋体">如何在</span>dll<span style="font-family: 宋体">中定义输出函数</span></h1>
<p><span style="font-family: 宋体">总体来说有两种方法，一种是添加一个</span>def<span style="font-family: 宋体">定义文件，在此文件中定义</span>dll<span style="font-family: 宋体">中要输出的函数；第二种是在源代码中待输出的函数前加上</span>__declspec(dllexport)<span style="font-family: 宋体">关键字。</span></p>
<h1>Def<span style="font-family: 宋体">文件</span></h1>
<p><span style="font-family: 宋体">首先写一个带有输出函数的</span>dll<span style="font-family: 宋体">，源代码如下：</span>dll_def.cpp</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>#include &lt;objbase.h&gt;</p>
<p>#include &lt;iostream.h&gt;</p>
<p>void FuncInDll (void)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; cout&lt;&lt;"FuncInDll is called!"&lt;&lt;endl;</p>
<p>}</p>
<p>BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved) </p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; HANDLE g_hModule;</p>
<p>&nbsp;&nbsp;&nbsp; switch(dwReason)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp; case DLL_PROCESS_ATTACH:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g_hModule = (HINSTANCE)hModule;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</p>
<p>&nbsp;&nbsp;&nbsp; case DLL_PROCESS_DETACH:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;g_hModule=NULL;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;break;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; return TRUE;</p>
<p>}</p>
</div>
<p><span style="font-family: 宋体">这个</span>dll<span style="font-family: 宋体">的</span>def<span style="font-family: 宋体">文件如下：</span>dll_def.def</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>;</p>
<p>; dll_def module-definition file</p>
<p>;</p>
<p>LIBRARY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dll_def.dll</p>
<p>DESCRIPTION&nbsp;&nbsp;&nbsp;&nbsp; '(c)2007-2009 Wang Xuebin'</p>
<p>EXPORTS</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FuncInDll @1&nbsp;PRIVATE</p>
</div>
<p><span style="font-family: 宋体">你会发现</span>def<span style="font-family: 宋体">的语法很简单，首先是</span>LIBRARY<span style="font-family: 宋体">关键字，指定</span>dll<span style="font-family: 宋体">的名字；然后一个可选的关键字</span>DESCRIPTION<span style="font-family: 宋体">，后面写上版权等信息（不写也可以）；最后是</span>EXPORTS<span style="font-family: 宋体">关键字，后面写上</span>dll<span style="font-family: 宋体">中所有要输出的函数名或变量名，然后接上</span>@<span style="font-family: 宋体">以及依次编号的数字（从</span>1<span style="font-family: 宋体">到</span>N<span style="font-family: 宋体">），最后接上修饰符。</span></p>
<p><span style="font-family: 宋体">用如下命令编译链接带有</span>def<span style="font-family: 宋体">文件的</span>dll<span style="font-family: 宋体">：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>Cl /c dll_def.cpp</p>
<p>Link /dll dll_def.obj /def:dll_def.def</p>
</div>
<p><span style="font-family: 宋体">再调用</span>dumpbin<span style="font-family: 宋体">查看生成的</span>dll_def.dll<span style="font-family: 宋体">：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>Dumpbin &#8211;exports dll_def.dll</p>
</div>
<p><span style="font-family: 宋体">得到如下结果：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>Dump of file dll_def.dll</p>
<p>File Type: DLL</p>
<p>&nbsp;Section contains the following exports for dll_def.dll</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 characteristics</p>
<p>&nbsp;&nbsp;&nbsp; 46E4EE98 time date stamp Mon Sep 10 15:13:28 2007</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 version</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 ordinal base</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 number of functions</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 number of names</p>
<p>&nbsp;&nbsp;&nbsp; ordinal hint RVA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; 0 00001000 FuncInDll</p>
<p>&nbsp;Summary</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2000 .data</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000 .rdata</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000 .reloc</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6000 .text</p>
</div>
<p><span style="font-family: 宋体">观察这一行</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; 0 00001000 FuncInDll</p>
</div>
<p><span style="font-family: 宋体">会发现该</span>dll<span style="font-family: 宋体">输出了函数</span>FuncInDll<span style="font-family: 宋体">。</span></p>
<h1><span style="font-family: 宋体">显式调用</span>DLL<span style="font-family: 宋体">中的函数</span></h1>
<p><span style="font-family: 宋体">写一个</span>dll_def.dll<span style="font-family: 宋体">的客户端程序：</span>dll_def_client.cpp</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>#include &lt;windows.h&gt;</p>
<p>#include &lt;iostream.h&gt;</p>
<p>int main(void)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; //<span style="font-family: 宋体">定义一个函数指针</span></p>
<p>&nbsp;&nbsp;&nbsp; typedef void (* DLLWITHLIB )(void);&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; //<span style="font-family: 宋体">定义一个函数指针变量</span></p>
<p>&nbsp;&nbsp;&nbsp; DLLWITHLIB pfFuncInDll = NULL;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; //<span style="font-family: 宋体">加载我们的</span>dll</p>
<p>&nbsp;&nbsp;&nbsp; HINSTANCE hinst=::LoadLibrary("dll_def.dll");&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; if (NULL != hinst)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;"dll loaded!"&lt;&lt;endl;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; //<span style="font-family: 宋体">找到</span>dll<span style="font-family: 宋体">的</span>FuncInDll<span style="font-family: 宋体">函数</span></p>
<p>&nbsp;&nbsp;&nbsp; pfFuncInDll = (DLLWITHLIB)GetProcAddress(hinst, "FuncInDll");&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; //<span style="font-family: 宋体">调用</span>dll<span style="font-family: 宋体">里的函数</span></p>
<p>&nbsp;&nbsp;&nbsp; if (NULL != pfFuncInDll)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*pfFuncInDll)();&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; return 0;</p>
<p>}</p>
</div>
<p><span style="font-family: 宋体">有两个地方值得注意，第一是函数指针的定义和使用，不懂的随便找本</span>c++<span style="font-family: 宋体">书看看；第二是</span>GetProcAddress<span style="font-family: 宋体">的使用，这个</span>API<span style="font-family: 宋体">是用来查找</span>dll<span style="font-family: 宋体">中的函数地址的，第一个参数是</span>DLL<span style="font-family: 宋体">的句柄，即</span>LoadLibrary<span style="font-family: 宋体">返回的句柄，第二个参数是</span>dll<span style="font-family: 宋体">中的函数名称，即</span>dumpbin<span style="font-family: 宋体">中输出的函数名（注意，这里的函数名称指的是编译后的函数名，不一定等于</span>dll<span style="font-family: 宋体">源代码中的函数名）。</span></p>
<p><span style="font-family: 宋体">编译链接这个客户端程序，并执行会得到：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>dll loaded!</p>
<p>FuncInDll is called!</p>
</div>
<p><span style="font-family: 宋体">这表明客户端成功调用了</span>dll<span style="font-family: 宋体">中的函数</span>FuncInDll<span style="font-family: 宋体">。</span></p>
<h1>__declspec(dllexport)</h1>
<p><span style="font-family: 宋体">为每个</span>dll<span style="font-family: 宋体">写</span>def<span style="font-family: 宋体">显得很繁杂，目前</span>def<span style="font-family: 宋体">使用已经比较少了，更多的是使用</span>__declspec(dllexport)<span style="font-family: 宋体">在源代码中定义</span>dll<span style="font-family: 宋体">的输出函数。</span></p>
<p>Dll<span style="font-family: 宋体">写法同上，去掉</span>def<span style="font-family: 宋体">文件，并在每个要输出的函数前面加上声明</span>__declspec(dllexport)<span style="font-family: 宋体">，例如：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>__declspec(dllexport) void FuncInDll (void)</p>
</div>
<p><span style="font-family: 宋体">这里提供一个</span>dll<span style="font-family: 宋体">源程序</span>dll_withlib.cpp<span style="font-family: 宋体">，然后编译链接。链接时不需要指定</span>/DEF:<span style="font-family: 宋体">参数，直接加</span>/DLL<span style="font-family: 宋体">参数即可，</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>Cl /c dll_withlib.cpp</p>
<p>Link /dll dll_withlib.obj</p>
</div>
<p><span style="font-family: 宋体">然后使用</span>dumpbin<span style="font-family: 宋体">命令查看，得到：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>1&nbsp;&nbsp;&nbsp; 0 00001000 ?FuncInDll@@YAXXZ</p>
</div>
<p><span style="font-family: 宋体">可知编译后的函数名为</span>?FuncInDll@@YAXXZ<span style="font-family: 宋体">，而并不是</span>FuncInDll<span style="font-family: 宋体">，这是因为</span>c++<span style="font-family: 宋体">编译器基于函数重载的考虑，会更改函数名，这样使用显式调用的时候，也必须使用这个更改后的函数名，这显然给客户带来麻烦。为了避免这种现象，可以使用</span>extern &#8220;C&#8221;<span style="font-family: 宋体">指令来命令</span>c++<span style="font-family: 宋体">编译器以</span>c<span style="font-family: 宋体">编译器的方式来命名该函数。修改后的函数声明为：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>extern "C" __declspec(dllexport)&nbsp;void FuncInDll (void)</p>
</div>
<p>dumpbin<span style="font-family: 宋体">命令结果：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>1&nbsp;&nbsp;&nbsp; 0 00001000 FuncInDll</p>
</div>
<p><span style="font-family: 宋体">这样，显式调用时只需查找函数名为</span>FuncInDll<span style="font-family: 宋体">的函数即可成功。</span></p>
<h1>extern &#8220;C&#8221;</h1>
<p><span style="font-family: 宋体">使用</span>extern &#8220;C&#8221;<span style="font-family: 宋体">关键字实际上相当于一个编译器的开关，它可以将</span>c++<span style="font-family: 宋体">语言的函数编译为</span>c<span style="font-family: 宋体">语言的函数名称。即保持编译后的函数符号名等于源代码中的函数名称。</span></p>
<h1><span style="font-family: 宋体">隐式调用</span>DLL</h1>
<p><span style="font-family: 宋体">显式调用显得非常复杂，每次都要</span>LoadLibrary<span style="font-family: 宋体">，并且每个函数都必须使用</span>GetProcAddress<span style="font-family: 宋体">来得到函数指针，这对于大量使用</span>dll<span style="font-family: 宋体">函数的客户是一种困扰。而隐式调用能够像使用</span>c<span style="font-family: 宋体">函数库一样使用</span>dll<span style="font-family: 宋体">中的函数，非常方便快捷。</span></p>
<p><span style="font-family: 宋体">下面是一个隐式调用的例子：</span>dll<span style="font-family: 宋体">包含两个文件</span>dll_withlibAndH.cpp<span style="font-family: 宋体">和</span>dll_withlibAndH.h<span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">代码如下：</span>dll_withlibAndH.h</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>extern "C" __declspec(dllexport)&nbsp;void FuncInDll (void);</p>
</div>
<p>dll_withlibAndH.cpp</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>#include &lt;objbase.h&gt;</p>
<p>#include &lt;iostream.h&gt;</p>
<p>#include "dll_withLibAndH.h"//<span style="font-family: 宋体">看到没有，这就是我们增加的头文件</span></p>
<p>extern "C" __declspec(dllexport)&nbsp;void FuncInDll (void)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; cout&lt;&lt;"FuncInDll is called!"&lt;&lt;endl;</p>
<p>}</p>
<p>BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved) </p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; HANDLE g_hModule;</p>
<p>&nbsp;&nbsp;&nbsp; switch(dwReason)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp; case DLL_PROCESS_ATTACH:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g_hModule = (HINSTANCE)hModule;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</p>
<p>&nbsp;&nbsp;&nbsp; case DLL_PROCESS_DETACH:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;g_hModule=NULL;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;break;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; return TRUE;</p>
<p>}</p>
</div>
<p><span style="font-family: 宋体">编译链接命令：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>Cl /c dll_withlibAndH.cpp</p>
<p>Link /dll dll_withlibAndH.obj</p>
</div>
<p><span style="font-family: 宋体">在进行隐式调用的时候需要在客户端引入头文件，并在链接时指明</span>dll<span style="font-family: 宋体">对应的</span>lib<span style="font-family: 宋体">文件（</span>dll<span style="font-family: 宋体">只要有函数输出，则链接的时候会产生一个与</span>dll<span style="font-family: 宋体">同名的</span>lib<span style="font-family: 宋体">文件）位置和名称。然后如同调用</span>api<span style="font-family: 宋体">函数库中的函数一样调用</span>dll<span style="font-family: 宋体">中的函数，不需要显式的</span>LoadLibrary<span style="font-family: 宋体">和</span>GetProcAddress<span style="font-family: 宋体">。使用最为方便。客户端代码如下：</span>dll_withlibAndH_client.cpp</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>#include "dll_withLibAndH.h"</p>
<p>//<span style="font-family: 宋体">注意路径，加载</span> dll<span style="font-family: 宋体">的另一种方法是</span> Project | setting | link <span style="font-family: 宋体">设置里</span></p>
<p>#pragma comment(lib,"dll_withLibAndH.lib")</p>
<p>int main(void)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; FuncInDll();//<span style="font-family: 宋体">只要这样我们就可以调用</span>dll<span style="font-family: 宋体">里的函数了</span></p>
<p>&nbsp;&nbsp;&nbsp; return 0;</p>
<p>}</p>
</div>
<h1>__declspec(dllexport)<span style="font-family: 宋体">和</span>__declspec(dllimport)<span style="font-family: 宋体">配对使用</span></h1>
<p><span style="font-family: 宋体">上面一种隐式调用的方法很不错，但是在调用</span>DLL<span style="font-family: 宋体">中的对象和重载函数时会出现问题。因为使用</span>extern &#8220;C&#8221;<span style="font-family: 宋体">修饰了输出函数，因此重载函数肯定是会出问题的，因为它们都将被编译为同一个输出符号串（</span>c<span style="font-family: 宋体">语言是不支持重载的）。</span></p>
<p><span style="font-family: 宋体">事实上不使用</span>extern &#8220;C&#8221;<span style="font-family: 宋体">是可行的，这时函数会被编译为</span>c++<span style="font-family: 宋体">符号串，例如（</span>?FuncInDll@@YAXH@Z<span style="font-family: 宋体">、</span> ?FuncInDll@@YAXXZ<span style="font-family: 宋体">），当客户端也是</span>c++<span style="font-family: 宋体">时，也能正确的隐式调用。</span></p>
<p><span style="font-family: 宋体">这时要考虑一个情况：若</span>DLL1.CPP<span style="font-family: 宋体">是源，</span>DLL2.CPP<span style="font-family: 宋体">使用了</span>DLL1<span style="font-family: 宋体">中的函数，但同时</span>DLL2<span style="font-family: 宋体">也是一个</span>DLL<span style="font-family: 宋体">，也要输出一些函数供</span>Client.CPP<span style="font-family: 宋体">使用。那么在</span>DLL2<span style="font-family: 宋体">中如何声明所有的函数，其中包含了从</span>DLL1<span style="font-family: 宋体">中引入的函数，还包括自己要输出的函数。这个时候就需要同时使用</span>__declspec(dllexport)<span style="font-family: 宋体">和</span>__declspec(dllimport)<span style="font-family: 宋体">了。前者用来修饰本</span>dll<span style="font-family: 宋体">中的输出函数，后者用来修饰从其它</span>dll<span style="font-family: 宋体">中引入的函数。</span></p>
<p><span style="font-family: 宋体">所有的源代码包括</span>DLL1.H<span style="font-family: 宋体">，</span>DLL1.CPP<span style="font-family: 宋体">，</span>DLL2.H<span style="font-family: 宋体">，</span>DLL2.CPP<span style="font-family: 宋体">，</span>Client.cpp<span style="font-family: 宋体">。源代码可以在下载的包中找到。你可以编译链接并运行试试。</span></p>
<p><span style="font-family: 宋体">值得关注的是</span>DLL1<span style="font-family: 宋体">和</span>DLL2<span style="font-family: 宋体">中都使用的一个编码方法，见</span>DLL2.H</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>#ifdef DLL_DLL2_EXPORTS</p>
<p>#define DLL_DLL2_API __declspec(dllexport)</p>
<p>#else</p>
<p>#define DLL_DLL2_API __declspec(dllimport)</p>
<p>#endif</p>
<p>DLL_DLL2_API void FuncInDll2(void);</p>
<p>DLL_DLL2_API void FuncInDll2(int);</p>
</div>
<p><span style="font-family: 宋体">在头文件中以这种方式定义宏</span>DLL_DLL2_EXPORTS<span style="font-family: 宋体">和</span>DLL_DLL2_API<span style="font-family: 宋体">，可以确保</span>DLL<span style="font-family: 宋体">端的函数用</span>__declspec(dllexport)<span style="font-family: 宋体">修饰，而客户端的函数用</span>__declspec(dllimport)<span style="font-family: 宋体">修饰。当然，记得在编译</span>dll<span style="font-family: 宋体">时加上参数</span>/D &#8220;DLL_DLL2_EXPORTS&#8221;<span style="font-family: 宋体">，或者干脆就在</span>dll<span style="font-family: 宋体">的</span>cpp<span style="font-family: 宋体">文件第一行加上</span>#define DLL_DLL2_EXPORTS<span style="font-family: 宋体">。</span></p>
<p>VC<span style="font-family: 宋体">生成的代码也是这样的！事实证明，我是抄袭它的，</span>hoho<span style="font-family: 宋体">！</span></p>
<h1>DLL<span style="font-family: 宋体">中的全局变量和对象</span></h1>
<p><span style="font-family: 宋体">解决了重载函数的问题，那么</span>dll<span style="font-family: 宋体">中的全局变量和对象都不是问题了，只是有一点语法需要注意。如源代码所示：</span>dll_object.h</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>#ifdef DLL_OBJECT_EXPORTS</p>
<p>#define DLL_OBJECT_API __declspec(dllexport)</p>
<p>#else</p>
<p>#define DLL_OBJECT_API __declspec(dllimport)</p>
<p>#endif</p>
<p>DLL_OBJECT_API void FuncInDll(void);</p>
<p>extern DLL_OBJECT_API int g_nDll;</p>
<p>class DLL_OBJECT_API CDll_Object {</p>
<p>public:</p>
<p>&nbsp;&nbsp;&nbsp; CDll_Object(void);</p>
<p>&nbsp;&nbsp;&nbsp; show(void);</p>
<p>&nbsp;&nbsp;&nbsp; // TODO: add your methods here.</p>
<p>};</p>
</div>
<p>Cpp<span style="font-family: 宋体">文件</span>dll_object.cpp<span style="font-family: 宋体">如下：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>#define DLL_OBJECT_EXPORTS </p>
<p>#include &lt;objbase.h&gt;</p>
<p>#include &lt;iostream.h&gt;</p>
<p>#include "dll_object.h"</p>
<p>DLL_OBJECT_API void FuncInDll(void)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; cout&lt;&lt;"FuncInDll is called!"&lt;&lt;endl;</p>
<p>}</p>
<p>DLL_OBJECT_API int g_nDll = 9;</p>
<p>CDll_Object::CDll_Object()</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; cout&lt;&lt;"ctor of CDll_Object"&lt;&lt;endl;</p>
<p>}</p>
<p>CDll_Object::show()</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; cout&lt;&lt;"function show in class CDll_Object"&lt;&lt;endl;</p>
<p>}</p>
<p>BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved) </p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; HANDLE g_hModule;</p>
<p>&nbsp;&nbsp;&nbsp; switch(dwReason)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp; case DLL_PROCESS_ATTACH:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g_hModule = (HINSTANCE)hModule;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</p>
<p>&nbsp;&nbsp;&nbsp; case DLL_PROCESS_DETACH:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;g_hModule=NULL;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;break;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; return TRUE;</p>
<p>}</p>
</div>
<p><span style="font-family: 宋体">编译链接完后</span>Dumpbin<span style="font-family: 宋体">一下，可以看到输出了</span>5<span style="font-family: 宋体">个符号：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>1&nbsp;&nbsp;&nbsp; 0 00001040 ??0CDll_Object@@QAE@XZ</p>
<p>&nbsp;2&nbsp;&nbsp;&nbsp; 1 00001000 ??4CDll_Object@@QAEAAV0@ABV0@@Z</p>
<p>&nbsp;3&nbsp;&nbsp;&nbsp; 2 00001020 ?FuncInDll@@YAXXZ</p>
<p>&nbsp;4&nbsp;&nbsp;&nbsp; 3 00008040 ?g_nDll@@3HA</p>
<p>&nbsp;5&nbsp;&nbsp;&nbsp; 4 00001069 ?show@CDll_Object@@QAEHXZ</p>
</div>
<p><span style="font-family: 宋体">它们分别代表类</span>CDll_Object<span style="font-family: 宋体">，类的构造函数，</span>FuncInDll<span style="font-family: 宋体">函数，全局变量</span>g_nDll<span style="font-family: 宋体">和类的成员函数</span>show<span style="font-family: 宋体">。下面是客户端代码：</span>dll_object_client.cpp</p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: #a6a6a6; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>#include "dll_object.h"</p>
<p>#include &lt;iostream.h&gt;</p>
<p>//<span style="font-family: 宋体">注意路径，加载</span> dll<span style="font-family: 宋体">的另一种方法是</span> Project | setting | link <span style="font-family: 宋体">设置里</span></p>
<p>#pragma comment(lib,"dll_object.lib")</p>
<p>int main(void)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; cout&lt;&lt;"call dll"&lt;&lt;endl;</p>
<p>&nbsp;&nbsp;&nbsp; cout&lt;&lt;"call function in dll"&lt;&lt;endl;</p>
<p>&nbsp;&nbsp;&nbsp; FuncInDll();//<span style="font-family: 宋体">只要这样我们就可以调用</span>dll<span style="font-family: 宋体">里的函数了</span></p>
<p>&nbsp;&nbsp;&nbsp; cout&lt;&lt;"global var in dll g_nDll ="&lt;&lt;g_nDll&lt;&lt;endl;</p>
<p>&nbsp;&nbsp;&nbsp; cout&lt;&lt;"call member function of class CDll_Object in dll"&lt;&lt;endl;</p>
<p>&nbsp;&nbsp;&nbsp; CDll_Object obj;</p>
<p>&nbsp;&nbsp;&nbsp; obj.show();</p>
<p>&nbsp;&nbsp;&nbsp; return 0;</p>
<p>}</p>
</div>
<p><span style="font-family: 宋体">运行这个客户端可以看到：</span></p>
<div style="border-right: windowtext 1pt solid; padding-right: 4pt; border-top: windowtext 1pt solid; padding-left: 4pt; background: silver; padding-bottom: 1pt; border-left: windowtext 1pt solid; padding-top: 1pt; border-bottom: windowtext 1pt solid">
<p>call dll</p>
<p>call function in dll</p>
<p>FuncInDll is called!</p>
<p>global var in dll g_nDll =9</p>
<p>call member function of class CDll_Object in dll</p>
<p>ctor of CDll_Object</p>
<p>function show in class CDll_Object</p>
</div>
<p><span style="font-family: 宋体">可知，在客户端成功的访问了</span>dll<span style="font-family: 宋体">中的全局变量，并创建了</span>dll<span style="font-family: 宋体">中定义的</span>C++<span style="font-family: 宋体">对象，还调用了该对象的成员函数。</span></p>
<h1><span style="font-family: 宋体">中间的小结</span></h1>
<p><span style="font-family: 宋体">牢记一点，说到底，</span>DLL<span style="font-family: 宋体">是对应</span>C<span style="font-family: 宋体">语言的动态链接技术，在输出</span>C<span style="font-family: 宋体">函数和变量时显得方便快捷；而在输出</span>C++<span style="font-family: 宋体">类、函数时需要通过各种手段，而且也并没有完美的解决方案，除非客户端也是</span>c++<span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">记住，只有</span>COM<span style="font-family: 宋体">是对应</span>C++<span style="font-family: 宋体">语言的技术。</span></p>
<p><span style="font-family: 宋体">下面开始对各各问题一一小结。</span></p>
<h1><span style="font-family: 宋体">显式调用和隐式调用</span></h1>
<p><span style="font-family: 宋体">何时使用显式调用？何时使用隐式调用？我认为，只有一个时候使用显式调用是合理的，就是当客户端不是</span>C/C++<span style="font-family: 宋体">的时候。这时是无法隐式调用的。例如用</span>VB<span style="font-family: 宋体">调用</span>C++<span style="font-family: 宋体">写的</span>dll<span style="font-family: 宋体">。（</span>VB<span style="font-family: 宋体">我不会，所以没有例子）</span></p>
<h1>Def<span style="font-family: 宋体">和</span>__declspec(dllexport)</h1>
<p><span style="font-family: 宋体">其实</span>def<span style="font-family: 宋体">的功能相当于</span>extern &#8220;C&#8221; __declspec(dllexport)<span style="font-family: 宋体">，所以它也仅能处理</span>C<span style="font-family: 宋体">函数，而不能处理重载函数。而</span>__declspec(dllexport)<span style="font-family: 宋体">和</span>__declspec(dllimport)<span style="font-family: 宋体">配合使用能够适应任何情况，因此</span>__declspec(dllexport)<span style="font-family: 宋体">是更为先进的方法。所以，目前普遍的看法是不使用</span>def<span style="font-family: 宋体">文件，我也同意这个看法。</span></p>
<h1><span style="font-family: 宋体">从其它语言调用</span>DLL</h1>
<p><span style="font-family: 宋体">从其它编程语言中调用</span>DLL<span style="font-family: 宋体">，有两个最大的问题，第一个就是函数符号的问题，前面已经多次提过了。这里有个两难选择，若使用</span>extern &#8220;C&#8221;<span style="font-family: 宋体">，则函数名称保持不变，调用较方便，但是不支持函数重载等一系列</span>c++<span style="font-family: 宋体">功能；若不使用</span>extern &#8220;C&#8221;<span style="font-family: 宋体">，则调用前要查看编译后的符号，非常不方便。</span></p>
<p><span style="font-family: 宋体">第二个问题就是函数调用压栈顺序的问题，即</span>__cdecl<span style="font-family: 宋体">和</span>__stdcall<span style="font-family: 宋体">的问题。</span>__cdecl<span style="font-family: 宋体">是常规的</span>C/C++<span style="font-family: 宋体">调用约定，这种调用约定下，函数调用后栈的清理工作是由调用者完成的。</span>__stdcall<span style="font-family: 宋体">是标准的调用约定，即这些函数将在返回到调用者之前将参数从栈中删除。</span></p>
<p><span style="font-family: 宋体">这两个问题</span>DLL<span style="font-family: 宋体">都不能很好的解决，只能说凑合着用。但是在</span>COM<span style="font-family: 宋体">中，都得到了完美的解决。所以，要在</span>Windows<span style="font-family: 宋体">平台实现语言无关性，还是只有使用</span>COM<span style="font-family: 宋体">中间件。</span></p>
<p><span style="font-family: 宋体">总而言之，除非客户端也使用</span>C++<span style="font-family: 宋体">，否则</span>dll<span style="font-family: 宋体">是不便于支持函数重载、类等</span>c++<span style="font-family: 宋体">特性的。</span>DLL<span style="font-family: 宋体">对</span>c<span style="font-family: 宋体">函数的支持很好，我想这也是为什么</span>windows<span style="font-family: 宋体">的函数库使用</span>C<span style="font-family: 宋体">加</span>dll<span style="font-family: 宋体">实现的理由之一。</span></p>
<h1><span style="font-family: 宋体">在</span>VC<span style="font-family: 宋体">中编写</span>DLL</h1>
<p><span style="font-family: 宋体">在</span>VC<span style="font-family: 宋体">中创建、编译、链接</span>dll<span style="font-family: 宋体">是非常方便的，点击</span>file<span style="font-family: Wingdings">&#224;</span>New<span style="font-family: Wingdings">&#224;</span>Project<span style="font-family: Wingdings">&#224;</span>Win32 Dynamic-Link Library<span style="font-family: 宋体">，输入</span>dll<span style="font-family: 宋体">名称</span>dll_InVC<span style="font-family: 宋体">然后点击确定。然后选择</span>A DLL that export some symbols<span style="font-family: 宋体">，点击</span>Finish<span style="font-family: 宋体">。即可得到一个完整的</span>DLL<span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">仔细观察其源代码，是不是有很多地方似曾相识啊，哈哈！</span></p>
<h1><span style="font-family: 宋体">最后</span></h1>
<p><span style="font-family: 宋体">贴上女儿近照一张，小家伙长得太快了</span>!</p>
<img style="width: 680px; height: 510px" height="510" alt="" src="http://www.blogjava.net/images/blogjava_net/wxb_nudt/baby/DSC02022.jpg" width="680" border="0" />
<img src ="http://www.blogjava.net/wxb_nudt/aggbug/144371.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wxb_nudt/" target="_blank">wxb_nudt</a> 2007-09-11 22:13 <a href="http://www.blogjava.net/wxb_nudt/archive/2007/09/11/144371.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最近不能上网</title><link>http://www.blogjava.net/wxb_nudt/archive/2007/06/27/126590.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Wed, 27 Jun 2007 06:56:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2007/06/27/126590.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/126590.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2007/06/27/126590.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/126590.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/126590.html</trackback:ping><description><![CDATA[最近不能上网，所以也不能更新了，请谅解。<br>大概需要半年才能重新上网了。
<img src ="http://www.blogjava.net/wxb_nudt/aggbug/126590.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wxb_nudt/" target="_blank">wxb_nudt</a> 2007-06-27 14:56 <a href="http://www.blogjava.net/wxb_nudt/archive/2007/06/27/126590.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>