📄 附录a0 建构环境.htm
字号:
<TBODY>
<TR>
<TD></TD></TR></TBODY></TABLE>
<DIV class=content id=ArticleBody
style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">
<P class=content></P>
<DIV style="WIDTH: 650px">
<P align=center><B><FONT color=#3e80d7 size=5><SPAN
style="BACKGROUND-COLOR: #d7d7d7">附录A 建构环境</SPAN></FONT></B></P>
<DIV language=javascript id=tab1
style="MARGIN-LEFT: 20px; LINE-HEIGHT: 25px"
ondragover="return tab1_ondragover()"><FONT
style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>为了建立本书之范例应用程序,您必须处理编译器与连结器的设定部份。我试着将这些设定细节放在单一的CmnHdr.h标头档中,使它们可以从范例应用程序中隔离出来,它们被包含在所有范例应用程序的原始程序文件中。</FONT>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>由于没有办法将所有的设定放在CmnHdr.h中,所以我在Project
Settings对话方块中对每个范例应用程序之专案设定做了一些修改:</FONT></P><FONT
style="LINE-HEIGHT: 25px" face=arial color=#000000 size=2>
<UL style="LINE-HEIGHT: 25px">
<LI style="LINE-HEIGHT: 25px">在General页签中,设定了Output Files
directory的内容,以使所有的 .exe与 .dll文件皆存放在单一的目录中。<BR
style="LINE-HEIGHT: 25px">
<LI style="LINE-HEIGHT: 25px">在C/C++ 页签中,我在Category清单中选择了Code
Generation category选项,并在Use Run-Time Library栏位中选择了Multithreaded
DLL选项。<BR style="LINE-HEIGHT: 25px"> </LI></UL></FONT>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>这些就是我唯一明确地修改设定的地方;其他部份则接受预设的设定。请注意,每个专案的debug与release模式做了上述二个修改。我在原始程序代码文件中设定了所有其他之编译器与连结器的设定,所以您要在专案中使用此原始码模组时,这些设定就会产生作用。</FONT></P><A
style="LINE-HEIGHT: 25px" name=101001>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7
size=5><B style="LINE-HEIGHT: 25px">CmnHdr.h标头文件<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>所有范例程序皆在引入其他标头档前将CmnHdr.h标头档引入,CmnHdr.h标头文件的内容放在此附录后的列表A-1中,以使工作变得轻松一点。该文件包含了巨集码、连结器的指示词以及其他贯穿所有范例应用程序的常见程序代码。当想尝试某些不同的东西时,需要做的事就是修改CmnHdr.h,然后重新建置所有范例应用程序。CmnHdr.h放置在随书光碟的根目录中。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>本附录剩馀的部份即是对CmnHdr.h标头文件的每个部份进行讨论,除了解释每部份的基本原理外,还描述该如何做以及为什么需要在重新建置范例应用程序前做这些修改的内容。</FONT></P></A><A
style="LINE-HEIGHT: 25px" name=101002>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7
size=5><B style="LINE-HEIGHT: 25px">迫使连结器寻找一个(w)WinMain进入点函数<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>在读者将此原始程序模组加到一个新的Microsoft Visual C++
专案并尝试建置该专案时,会接收到连结器的错误讯息。这个问题是因为他们建立了一个Win32 Console
Application专案,所以导致连结器会去寻找一个(w)main进入点函数。由于本书的范例应用程序皆为GUI应用程序,所以我的原始程序代码中皆以_tWinMain进入点函数取代,因此才会使连结器发出抱怨的讯息。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>针对这个问题的标准回应如下:删除该专案、使用Visual C++ 建立一个新的Win32
Application专案(请注意「Console」不该出现在此专案类别中),然后将此原始码文件加入。连结器会寻找一个(w)WinMain进入点函数,在此程序代码中已经提供此点,而得以适当地建置专案。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>为了减少将会因为此议题而收到的e-mail数量,我新增了一个pragma至CmnHdr.h中,以便您用Visual C++
建立了一个Win32 Console
Application专案时,可以强迫连结器寻找(w)WinMain进入点函数。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>在《Programming Applications for Microsoft Windows, Fourth
Edition》(Jeffrey Richter, Microsoft Press, 1999)一书的第四章中,详细讨论了Visual
C++ 之专案类型的相关内容、如何选择连结器应该寻找的进入点函数,以及如何覆写连结器的预设行为设定。</FONT></P></A><A
style="LINE-HEIGHT: 25px" name=101003>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7
size=5><B style="LINE-HEIGHT: 25px">Windows版本之建置选项<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>因为某些范例应用程序呼叫了Microsoft Windows 2000中的新增函数,CmnHdr.h将此部份定义为
_WIN32_WINNT符号,其内容如下:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">#define _WIN32_WINNT 0x0500</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>因为新的Windows
2000函数原型放在Windows标头文件中,所以必须定义此符号,其内容如下:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">#if (_WIN32_WINNT >= 0x0500) <BR>WINBASEAPI <BR>BOOL <BR>WINAPI <BR>AssignProcessToJobObject( <BR> IN HANDLE hJob, <BR> IN HANDLE hProcess <BR> ); <BR>#endif /*_WIN32_WINNT >= 0x0500 */</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>除非您像我一样特别定义
_WIN32_WINNT符号(在引入Windows.h前),否则新函数的原型不会被宣告,而且当您试图呼叫这些函数时,编译器将会产生错误讯息。Microsoft用
_WIN32_WINNT符号来保护这些函数,以帮助确认您所开发之可在多种Microsoft Windows NT与Microsoft
Windows 98版本中执行的应用程序。</FONT></P></A><A style="LINE-HEIGHT: 25px"
name=101004>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7
size=5><B style="LINE-HEIGHT: 25px">Unicode建置选项<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>大部份的范例应用程序皆可以被编译为ANSI或Unicode的型式。本书的主题为Windows
2000之服务编写,所以预设为Unicode的型式,因为它允许应用程序使用较少的内存并可更快速执行。然而,如果您想要在自己的ANSI应用程序中使这些程序代码也可以正常执行。</FONT></P>
<HR style="LINE-HEIGHT: 25px">
<P><FONT style="LINE-HEIGHT: 25px" face=Arial color=#3e77d7 size=3
Black><B style="LINE-HEIGHT: 25px">说明</B></FONT> </P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>在时间上,Microsoft在作业系统中已经新增了越来越多只支援Unicode的特色。例如,在第九章中讨论之管理受信任帐户的Net函数就只支援Unicode字串。因为这些函数出现在程序代码中,所以本书中的某些范例应用程序会编译成只支援Unicode的型式。请参阅《Programming
Applications for Microsoft Windows, Fourth
Edition》的第二章内容,以取得更多Unicode的相关资讯。</FONT></P>
<HR style="LINE-HEIGHT: 25px">
</A><A style="LINE-HEIGHT: 25px" name=101005>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7
size=5><B style="LINE-HEIGHT: 25px">Windows定义与Warning Level 4<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>当我在开发软件时,总是试着确认程序代码在经过编译后没有出现错误与警告讯息。我也喜欢在较高的警告层级下编译程序,所以编译器会为做了大部份的工作,甚至检查程序代码的最小细节。在Microsoft
C/C++ 编译器中,我使用Warning Level 4来建置所有的范例应用程序。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>在CmnHdr.h的这个部份中,我确认它的Warning
Level设定为4,而CmnHdr.h中引入了标准的Windows.h标头文件。在Warning level
4上,编译器会发出不需考虑问题的「warnings」事件,所以我明确地告诉编译器必须忽略某些使用#pragma
warning指示词之良性警告事件。</FONT></P></A><A style="LINE-HEIGHT: 25px"
name=101006>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7
size=5><B style="LINE-HEIGHT: 25px">pragma讯息协助程序巨集<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>当我在编写程序代码时,通常喜欢立即地执行某些工作,然后再将它修改得更完美。为了提醒自己必须修改某些程序代码,我加入了一行像这样的程序代码:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">#pragma message("Fix this later")</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>当编译器编译此行时,它会输出一个字串以提醒我必须做某些事;然而,这个讯息并不是很有帮助。所以我决定找出一个方法使得编译器输出原始程序代码文件的名称以及其中出现pragma的行号。有了这个资讯,不仅可以知道有某些事必须做,还可以立即了解应修改之程序代码的位置。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>为了输出原始程序代码文件以及行号,您必须有技巧的使用一系列pragma
message指示词之巨集程序代码。我将产生的巨集命名为chMSG,使用的方法就像这样:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">#pragma chMSG(Fix this later)</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>当此行被编译后,编译器会产生一行如下所示的讯息:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">C:\CD\CmnHdr.h(82):Fix this later</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>使用Microsoft Visual
Studio,您可以在输出视窗双击此行,它会自动地移到对应的程序代码上。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>chMSG巨集不需要在文字字串前后使用引号。</FONT></P></A><A
style="LINE-HEIGHT: 25px" name=101007>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7
size=5><B
style="LINE-HEIGHT: 25px">chINRANGE、chDIMOF以及chSIZEOFSTRING巨集<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>在应用程序中,频繁地使用了便于使用的chINRANGE、chDIMOF以及chSIZEOFSTRING巨集。第一个巨集为chINRANGE,检查一个值是否存在两个其他值之间;第二个巨集为chDIMOF,简单地回传阵列中的项目数,首先用sizeof运算子以位元组为单位,计算整个阵列的尺寸,然后再用阵列中之单一项目所需的位元组数字来划分此数目;第叁个巨集为chSIZEOFSTRING,回传一个被零终止字串占用的大小。</FONT></P></A><A
style="LINE-HEIGHT: 25px" name=101008>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -