﻿<?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, 06 Oct 2008 17:21:17 GMT</lastBuildDate><pubDate>Mon, 06 Oct 2008 17:21:17 GMT</pubDate><ttl>60</ttl><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>1</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>2</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>14</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>8</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>8</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>46</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><item><title>Java环境设置、HelloWorld例子、Ant环境及运行</title><link>http://www.blogjava.net/wxb_nudt/archive/2007/01/16/94268.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Tue, 16 Jan 2007 10:13:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2007/01/16/94268.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/94268.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2007/01/16/94268.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/94268.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/94268.html</trackback:ping><description><![CDATA[
		<p>一段时间不用Java，经常忘记一些烦琐的设置，特意写此文档备案。<br /><br />-------------<br />java环境设置<br />-------------</p>
		<p>在环境变量中设置以下三个变量：<br />JAVA_HOME=C:\j2sdk1.4.1 //可以改为相应的目录<br />CLASSPATH=%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar<br />PATH=%JAVA_HOME%\bin;%PATH%</p>
		<p>然后在命令行输入java -version命令，如果出现<br />java version "1.4.1"<br />Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)<br />Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)<br />则说明已经配置成功！</p>
		<p>HelloWorld.java源程序如下：<br />public class HelloWorld{ <br /> public static void main(String[] args) {  <br />  System.out.println("Hello World!"); <br />  }<br />}</p>
		<p>在命令行执行javac HelloWorld.java<br />如果没有输出任何信息则说明编译成功。</p>
		<p>在命令行运行java HelloWorld，输出：<br />Hello World!<br />代表成功执行了java程序。</p>
		<p>-----------------<br />初学者常犯的错误<br />-----------------</p>
		<p>1. 运行时，带了.class后缀<br />如果你试图使用如下命令：<br />E:\java\src&gt;java HelloWorld.class<br />系统会误认为你运行的是HelloWorld包下的名为class的类文件，会到系统的CLASSPATH下（一般都包括当前目录）企图寻找HelloWorld.class.class这样的类，这样的类当然不存在了；并且也不可能存在，因为class是关键字，不能作为一个类的名字。所以会报如下错误信息：<br />Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld/class</p>
		<p>2. 文件名大小写错误<br />对于像Windows这样的系统，编译时可以不关心大小写。比如编译HelloWorld.java时，也可以使用：<br />E:\java\src&gt;javac helloworld.java<br />也可以编译通过，但产生的类文件仍然是和源文件相符的：HelloWorld.class。<br />但在运行时一定要注意大小写，比如试图使用如下命令运行：<br />E:\java\src&gt;java helloworld<br />将报类似于1中的错误：<br />Exception in thread "main" java.lang.NoClassDefFoundError: helloworld (wrong name: HelloWorld)</p>
		<p>
				<br />----------------------------<br />包含包层次的HelloWorld.java<br />----------------------------</p>
		<p>比如上面的HelloWorld.java修改如下：<br />package org.javaresearch;<br />public class HelloWorld{<br />public static void main(String[] args) {<br />System.out.println("Hello World!"); <br />}<br />}</p>
		<p>编译时有两种方法</p>
		<p>1. 直接编译<br />E:\java\src&gt;javac HelloWorld.java<br />此时在当前目录下输出HelloWorld.class。此时，运行不能使用上面相同的方法，使用：<br />E:\java\src&gt;java HelloWorld<br />运行时，出现如下错误：<br />Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld (wrong name: org/javaresearch/HelloWorld)<br />从上述错误信息你也可以看到，系统可以找到HelloWorld类（因为当前路径包含在CLASSPATH中，具体为什么会提示wrong name，有兴趣的朋友参见Java语言规范），但这个类属于org.javaresearch包。所以，你要做的就是按照上述包层次，相应的创建目录层次，把上面生成的HelloWorld.class放到E:\java\src\org\javaresearch\目录下。运行：<br />E:\java\src &gt;java org.javaresearch.HelloWorld<br />系统打印出：<br />Hello World!<br />这儿要注意的是，不能使用java org\javaresearch\HelloWorld来运行，此时同样会出现如下错误：<br />Exception in thread "main" java.lang.NoClassDefFoundError:org\javaresearch\HelloWorld (wrong name: org/javaresearch/HelloWorld)</p>
		<p>2. 使用 -d &lt;directory&gt;编译选项<br />是不是觉得上面的编译方法有点麻烦，能不能自动在当前路径（或任意指定的路径）下生成包层次呢？有！使用-d &lt;directory&gt;编译选项就能做到。<br />E:\java\src &gt;javac -d . HelloWorld.java<br />此时，在当前目录下就生成了一个org\javaresearch目录，并且输出的.class文件也在里面。运行：<br />E:\java\src &gt;java org.javaresearch.HelloWorld<br />系统打印：Hello World!<br />如果你想把生成的类文件集中存放在一个目录中，比如：E:\java\classes下，那么你首先创建这个目录，然后编译时：<br />E:\java\src &gt;javac -d E:\java\classes HelloWorld.java<br />就可以把生成的类文件放到E:\java\classes目录下，并且按照包层次相应的创建目录路径。你可以在E:\java\classes\org\javaresearch下找到HelloWorld.class文件。此时使用如下命令可以正确运行（注意如果要用到其它类，请在CLASSPATH中设好）：<br />E:\java\classes &gt;java org.javaresearch.HelloWorld</p>
		<p>或者你可以在E:\java目录下面运行以下命令来执行<br />E:\java &gt;java -classpath .\classes org.javaresearch.HelloWorld<br />使用java的-classpath参数可以将一些目录加入类路径</p>
		<p>-------------------<br />打包jar文件<br />-------------------<br />可以把一个包内的所有class文件打包为一个jar文件，便于存放和运行。以上文的org.javaresearch包为例，其打包命令如下：<br />E:\java\classes &gt;jar cvf wxb.jar org<br />会生成一个wxb.jar文件，将其中META-INF\MANIFEST.MF文件中添加如下一行：<br />Main-Class: org.javaresearch.HelloWorld<br />保存jar文件。</p>
		<p>或者首先创建并编辑一个MANIFEST.MF文件，其内容如下：<br />Manifest-Version: 1.0<br />Created-By: 1.4.1 (Sun Microsystems Inc.)<br />Main-Class: org.javaresearch.HelloWorld<br />将其保存到classes目录中<br />然后将其一起打包到jar文件中，打包命令如下：<br />E:\java\classes &gt;jar cvfm wxb.jar MANIFEST.MF org</p>
		<p>-------------<br />运行jar文件<br />-------------<br />在命令行中输入如下命令即可：<br />E:\java\classes &gt;java -jar wxb.jar<br />输出为：<br />Hello World!</p>
		<p>------------------------<br />用Ant来编译运行java程序<br />------------------------<br />首先安装Ant，步骤很简单：<br />1.将Ant压缩包解压到一个目录，例如D:\Ant1.5.2；<br />2.在环境变量中添加以下变量：<br />ANT_HOME=D:\Ant1.5.2  //可以改为相应的目录<br />3.修改Path环境变量<br />PATH=%ANT_HOME%\bin;%PATH%</p>
		<p>最后给出了一个Ant的build.xml文件，运行ant即可完成所有以上的编译和运行过程，其build文件如下：<br />&lt;project name="HelloWorld" default="jar" basedir="."&gt;<br />    &lt;description&gt;<br />        building HelloWorld!<br />    &lt;/description&gt;<br />  &lt;!-- set global properties for this build --&gt;<br />  &lt;property name="src" location="src"/&gt;<br />  &lt;property name="build" location="classes"/&gt;<br />  &lt;property name="dist"  location="dist"/&gt;<br />  &lt;property name="user.name" value="Wang Xuebin"/&gt;</p>
		<p>  &lt;target name="init"&gt;<br />    &lt;!-- Create the time stamp --&gt;<br />    &lt;tstamp/&gt;<br />    &lt;!-- Create the classes directory structure used by compile --&gt;<br />    &lt;mkdir dir="${build}"/&gt;<br />  &lt;/target&gt;</p>
		<p>  &lt;target name="build" depends="init"  description="build the source code" &gt;<br />    &lt;!-- Compile the java code from ${src} into ${build} --&gt;<br />    &lt;javac srcdir="${src}" destdir="${build}"/&gt;<br />  &lt;/target&gt;</p>
		<p>  &lt;target name="jar" depends="build"<br />        description="generate the distribution" &gt;<br />    &lt;!-- Create the distribution directory --&gt;<br />    &lt;mkdir dir="${dist}/lib"/&gt;</p>
		<p>    &lt;!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file --&gt;<br />  &lt;jar destfile="${dist}/HelloWorld-${DSTAMP}.jar" basedir="${build}"&gt;<br />   &lt;manifest&gt;<br />    &lt;attribute name="Built-By" value="${user.name}"/&gt;<br />    &lt;attribute name="Main-Class" value="org.javaresearch.HelloWorld"/&gt;<br />   &lt;/manifest&gt;<br />  &lt;/jar&gt;  <br /> &lt;/target&gt;<br />  <br />  &lt;target name="run" depends="build" description="run HelloWorld"&gt;<br />    &lt;java classpath="${build}" classname="org.javaresearch.HelloWorld"&gt;&lt;/java&gt;<br />  &lt;/target&gt;</p>
		<p>  &lt;target name="runjar" depends="jar" description="run HelloWorld in jar file"&gt;<br />         &lt;java jar="${dist}/HelloWorld-${DSTAMP}.jar"<br />           fork="true"<br />           failonerror="true"<br />           maxmemory="128m"<br />           &gt;<br />         &lt;arg value="-h"/&gt;<br />         &lt;classpath&gt;<br />           &lt;pathelement location="${dist}/HelloWorld-${DSTAMP}.jar"/&gt;<br />           &lt;pathelement path="${java.class.path}"/&gt;<br />         &lt;/classpath&gt;<br />       &lt;/java&gt;<br />  &lt;/target&gt;<br />  <br />  &lt;target name="clean"<br />        description="clean up" &gt;<br />    &lt;!-- Delete the ${build} and ${dist} directory trees --&gt;<br />    &lt;delete dir="${build}"/&gt;<br />    &lt;delete dir="${dist}"/&gt;<br />  &lt;/target&gt;<br />&lt;/project&gt;</p>
		<p>
				<br /> </p>
<img src ="http://www.blogjava.net/wxb_nudt/aggbug/94268.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-01-16 18:13 <a href="http://www.blogjava.net/wxb_nudt/archive/2007/01/16/94268.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP的Request对象在localhost下面发生的问题</title><link>http://www.blogjava.net/wxb_nudt/archive/2006/11/12/80765.html</link><dc:creator>wxb_nudt</dc:creator><author>wxb_nudt</author><pubDate>Sun, 12 Nov 2006 14:58:00 GMT</pubDate><guid>http://www.blogjava.net/wxb_nudt/archive/2006/11/12/80765.html</guid><wfw:comment>http://www.blogjava.net/wxb_nudt/comments/80765.html</wfw:comment><comments>http://www.blogjava.net/wxb_nudt/archive/2006/11/12/80765.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/wxb_nudt/comments/commentRss/80765.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wxb_nudt/services/trackbacks/80765.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最近帮朋友做一个简单网站，同时学习了一下</span>
				<span lang="EN-US">ASP</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">技术。在使用</span>
				<span lang="EN-US">Macromedia</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>
				<span lang="EN-US">IIS5.1</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时候发现了一个很容易让人迷惑的问题。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">配置如下：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">Macromedia 2004 MX</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">IIS 5.1</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">Windows XP SP2</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>
				<span lang="EN-US">Macromedia</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里面建立了一个站点可以直接将编辑的</span>
				<span lang="EN-US">ASP</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或者</span>
				<span lang="EN-US">HTML</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件上传到本地的</span>
				<span lang="EN-US">IIS</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录下面（默认为</span>
				<span lang="EN-US">C:\Inetpub\wwwroot</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），这样就可以直接点击一个按钮实现</span>
				<span lang="EN-US">ASP</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件在</span>
				<span lang="EN-US">IIS</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下面的效果御览。</span>
				<span lang="EN-US">Macromedia 2004 MX</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在设置站点是默认的</span>
				<span lang="EN-US">http</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">前缀是</span>
				<span lang="EN-US">http:://localhost</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。因此我的</span>
				<span lang="EN-US">ASP</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件出现在</span>
				<span lang="EN-US">IE</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里面的路径是</span>
				<span lang="EN-US">
						<a href="http://127.0.0.1/wxbsite/getName.asp">http://localhost/wxbsite/getName.asp</a>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。一切看起来都是那么美好。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">但是在运行下面一个简单例子是问题出现了：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件名：</span>
				<span lang="EN-US">getName.asp</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">说明：从文本框读入一个字符串，在点击</span>
				<span lang="EN-US">submit</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">按钮时将这个字符串显示在按钮下方</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">源代码：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%&gt;<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;html&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;head&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312"&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;title&gt;getName&lt;/title&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;/head&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;body&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;%<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">name = request.Form("txtName")<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">%&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;form method="POST" action="getName.asp"&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;input type="text" name="txtName" size="20" value="&lt;%=name%&gt;"&gt;&lt;p&gt;&lt;/p&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;input type="submit" value="submit"&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;/form&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;%<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">response.Write name<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">%&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;/body&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">&lt;/html&gt;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">问题如下：无论如何试验，均发现</span>
				<span lang="EN-US">request.Form("txtName")</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句不能得到有效值，而只是得到</span>
				<span lang="EN-US">null</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">修改</span>
				<span lang="EN-US">IIS</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">配置，无效；</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">修改</span>
				<span lang="EN-US">ASP</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件，将其拆分为</span>
				<span lang="EN-US">html</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>
				<span lang="EN-US">asp</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，无效；</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>
				<span lang="EN-US">google</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上面折腾好久，也发现了有人出现了类似的问题，但是没有答案。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最后发现，都是</span>
				<span lang="EN-US">localhost</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">惹的祸。将</span>
				<span lang="EN-US">http</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">头更换为</span>
				<span lang="EN-US">
						<a href="http://127.0.0.1/">http://127.0.0.1</a>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，则一切都正常了。郁闷啊，花费了一个小时的时间，得出了这个隐藏的</span>
				<span lang="EN-US">localhost</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</span>
				<span lang="EN-US">127.0.0.1</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的差别。奇怪的是，使用</span>
				<span lang="EN-US">response</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象输出语言却是正常的。看来</span>
				<span lang="EN-US">localhost</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只影响表单对象数据的传输！</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">记之！</span>
		</p>
<img src ="http://www.blogjava.net/wxb_nudt/aggbug/80765.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> 2006-11-12 22:58 <a href="http://www.blogjava.net/wxb_nudt/archive/2006/11/12/80765.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>