用html写一段简单的代码输出python hello worldd

Windows系统下用命令行编译C/C++程序过程总结 - caikehe - 博客园
随笔 - 4, 文章 - 0, 评论 - 5, 引用 - 0
前一段时间在自学linux系统,想模仿linux命令行的方式在Windows下编译C/C++程序,摸索一段时间后总算把这个解决了!
(1)先用记事本编写如下所示的代码,并另存为hello.cpp,假设其保存路径为C:\Users\Administrator\Desktop。
#include&iostream&
int main()
&&& cout&&"hello world!"&&
&&& return 0;
(2)用记事本写一段简单的批处理文件,内容如下所示,在保存文件时选择另存为,文件名假设为batch.bat,bat是批处理文件的后缀,保存类型选择:所有文件(这个尤其需要注意),假设其保存路径也是C:\Users\Administrator\Desktop。
set path=D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\bin
set include=D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\include
set lib=D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\lib
上面批处理文件的第一句话表示设置环境变量,这个也可以通过:计算机/属性/高级系统设置/环境变量/用户变量,D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\bin放到path的值里去,记得与之前已有值之间用";"隔开。这个path文件夹是我们装载VS2010时自带的,在设置路径时要根据自己的安装路径进行修改,里面包含微软在Windows下给我们提供的C/C++编译器cl.exe程序(编译器自身也是一个软件程序,只是它的作用是用来编译其它的程序),当然还有link.exe链接程序,调用cl时,系统会自动调用link程序(后面将看到我们只用了cl命令就可以进行C/C++程序的编译、链接)。后面两句话分别表示包含C++中自带的头文件库和静态链接库,静态理解库包含了头文件中函数对应的实现部分,为了不让人们看到其中的源代码,它以二进制文件形式编码,若要查看其内容需要进行反汇编。
(3)通过cmd命令进入DOS操作界面,输入cd C:\Users\Administrator\Desktop进入cpp文件和bat批处理文件所在的位置,然后键入batch.bat进行批处理,这些操作在VS2010集成开发环境中都为我设置好了,所以我们在里面写C/C++程序时并没有这样设置路径的繁琐操作,但是通过自己手动的路径设置,我们会对程序的编译、链接、执行有更加深入的认识。
(4)键入cl hello.cpp,我们会看到计算机报出了&无法启动此程序,因为计算机中丢失mspdb100.dll。尝试重新安装该程序以解决此问题&的系统储物,dll文件是动态链接库文件,其是在cl.exe程序运行时才被加载进来的文件,这个静态链接库lib文件不同。这说明在D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\bin路径里没有找到mspdb100.dll,原来此文件在文件夹D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\Common7\IDE里,我们可以将此文件拷到bin文件夹里,或将D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\Common7\IDE加到批处理的path环境变量里,或者将其加到cpp文件所在的文件夹里,这只会引起在搜索顺序上的不同。
(5)再次键入cl hello.cpp,我们看到在C:\Users\Administrator\Desktop文件夹里得到了hello.obj文件,这是编译后的输出文件,但是没有得到可执行exe文件,DOS界面里出现这样的错误&LINK:fatal error LNK1104:cannot open file 'kernel32.lib' &这样的链接错误,kernel32.lib是Windows系统文件,通过Windows自带的搜索工具,我们看到此文件在文件夹C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib里,我们可以将其加到cpp文件所在的文件夹或bin文件里。再次键入cl hello.cpp,我们发现这次程序被成功编译链接了,cpp文件所在的文件夹里多了两个文件:hello.obj和hello.exe。
(6)在DOS界面键入hello.exe,程序被执行,输出了我们预想的hello world!,至此,在Windows下模拟linux命令行操作,编译C/C++文件全部完成了。在之前写一篇文章《从数据到代码》(、)中,我通过基于CodeDOM+Custom Tool的代码生成方式实现了将一个XML表示的消息列表转换成了相应的C#代码,从而达到了强类型编程的目的。实际上,我们最常用的代码生成当时不是CodeDOM,而是T4,这是一个更为强大,并且适用范围更广的代码生成技术。今天,我将相同的例子通过T4的方式再实现一次,希望为那些对T4不了解的读者带来一些启示。同时这篇文章将作为后续文章的引子,在此之后,我将通过两篇文章通过具体实例的形式讲述如果在项目将T4为我所用,以达到提高开发效率和保证质量的目的。[有T4相关的资料][文中的例子可以从下载]
一、我们的目标是:从XML文件到C#代码
二、从Hello World讲起
三、T4模板的基本结构
四、通过T4模板实现从“数据到代码”的转变
五、T4的文本转化的实现
一、我们的目标是:从XML文件到C#代码
再次重申一下我们需要通过“代码生成”需要达到的目的。无论对于怎么样的应用,我们都需要维护一系列的消息。消息的类型很多,比如验证消息、确认消息、日志消息等。我们一般会将消息储存在一个文件或者数据库中进行维护,并提供一些API来获取相应的消息项。这些API一般都是基于消息的ID来获取的,换句话说,消息获取的方式是以一种“弱类型”的编程方式实现的。如果我们能够根据消息存储的内容动态地生成相应的C#或者VB.NET代码,那么我们就能够以一种强类型的方式来获取相应的消息项了。
比如说,现在我们定义了如下一个MessageEntry类型来表示一个消息条目。为了简单,我们尽量简化MessageEntry的定义,仅仅保留三个属性Id、Value和Category。Category表示该消息条目所属的类型,你可以根据具体的需要对其分类(比如根据模块名称或者Severity等)。Value是一个消息真实的内容,可以包含一些占位符({0},{1},…{N})。通过指定占位符对用的值,最中格式化后的文本通过Format返回。
1: public class MessageEntry
public string Id { private }
public string Value { private }
public string Category { private }
public MessageEntry(string id, string value, string category)
this.Value
this.Category
public string Format(params object[] args)
return string.Format(this.Value, args);
现在我们所有的消息定义在如下一个XML文件中,&message&XML元素代码一个具体的MessageEntry,相应的属性(Attribute)和MessageEntry的属性(Property)相对应。
1: &?xml version=&1.0& encoding=&utf-8& ?&
2: &messages&
&message id=&MandatoryField& value=&The {0} is mandatory.&
category=&Validation&/&
&message id=&GreaterThan& value=&The {0} must be greater than {1}.&
category=&Validation&/&
&message id=&ReallyDelete& value=&Do you really want to delete the {0}.&
category=&Confirmation&/&
6: &/messages&
在上面的XML中,定义了两个类别(Validation和Confirmation)的三条MessageEntry。我们需要通过我们的代码生成工具生成一个包含如下C#代码的CS文件。
1: public static class Messages
public static class Validation
public static MessageEntry MandatoryField = new MessageEntry(&MandatoryField&, &The {0} is mandatory.&, &Validation&);
public static MessageEntry GreaterThan = new MessageEntry(&GreaterThan&, &The {0} must be greater than {1}.&, &Validation&);
public static class Confirmation
public static MessageEntry ReallyDelete = new MessageEntry(&ReallyDelete&, &Do you really want to delete the {0}.&, &Confirmation&);
那么如何通过T4的方式来实现从“数据”(XML)到“代码”的转换呢?在投入到这个稍微复杂的工作之前,我们先来弄个简单的。
二、从Hello World讲起
我们之前一直在讲T4,可能还有人不知道T4到底代表什么。T4是对“Text Template Transformation Toolkit”(4个T)的简称。T4直接包含在VS2008和VS2010中,是一个基于文本文件转换的工具包。T4的核心是一个基于“文本模板”的转换引擎(以下简称T4引擎),我们可以通过它生成一切类型的文本型文件,比如我们常用的代码文件类型包括:C#、VB.NET、T-SQL、XML甚至是配置文件等。
对于需要通过T4来进行代码生成工作的我们来说,需要做的仅仅是根据转换源(Transformation Source),比如数据表、XML等(由于例子简单,HelloWord模板没有输入源)和目标文本(比如最终需要的C#或者T-SQL代码等)定义相应的模板。T4模板作用就相当于进行XML转化过程中使用的XSLT。
T4模板的定义非常简单,整个模板的内容包括两种形式:静态形式和动态动态。前者就是直接写在模板中作为原样输出的文本,后者是基于某种语言编写代码,T4引擎会动态执行它们。这和我们通过内联的方式编写的ASP.NET页面很相似:HTML是静态的,以C#或者VB.NET代码便写的动态执行的代码通过相应的标签内嵌其中。为了让读者对T4模板有一个直观的认识,我们先来尝试写一个最简单的。假设我们需要通过代码生成的方式生成如下一段简单的C#代码:
1: using S
3: namespace Artech.CodeGeneration
class Program
static void Main(string[] args)
Console.WriteLine(&Hello, {0}&, &Foo&);
Console.WriteLine(&Hello, {0}&, &Bar&);
Console.WriteLine(&Hello, {0}&, &Baz&);
现在我们直接通过VS来创建一个T4模板来生成我们期望的C#代码。右击项目文件,选择&Add&|&New Item&,在模板列表中选择&Text Template&。指定文件名后确定,一个后缀名为.tt的文件会被创建,然后在该文件中编写如下的代码。
1: &#@ template debug=&false& hostspecific=&false& language=&C#& #&
2: &#@ assembly name=&System.Core.dll& #&
3: &#@ import namespace=&System& #&
4: &#@ output extension=&.cs& #&
5: using S
7: namespace Artech.CodeGeneration
class Program
static void Main(string[] args)
foreach(var person in this.InitializePersonList())
Console.WriteLine(&Hello, {0}&,&&#=
person#&&);
public string[] InitializePersonList()
return new string[]{&Foo&,&Bar&,&Baz&};
保存该文件后,一个.cs文件将会作为该TT文件的附属文件被添加(如右图所示的HelloWorld.cs)。上述的这个TT文件虽然简单,却包含了构成一个T4模板的基本元素。在解读该T4模板之前,我们有必要先来了解一个完整的T4模板是如何构成的。
三、T4模板的基本结构
假设我们用“块”(Block)来表示构成T4模板的基本单元,它们基本上可以分成5类:指令块(Directive Block)、文本块(Text Block)、代码语句块(Statement Block)、表达式块(Expression Block)和类特性块(Class Feature Block)。
1、指令块(Directive Block)
和ASP.NET页面的指令一样,它们出现在文件头,通过&#@…#&表示。其中&#@ template …#&指令是必须的,用于定义模板的基本属性,比如编程语言、基于的文化、是否支持调式等等。比较常用的指令还包括用于程序集引用的&#@ assembly…#&,用于导入命名空间的&#@ import…#&等等。
2、文本块(Text Block)
文本块就是直接原样输出的静态文本,不需要添加任何的标签。在上面的模板文件中,处理定义在&#… #&、&#+… #&和&#=… #&中的文本都属于文本块。比如在指令块结束到第一个“&#”标签之间的内容就是一段静态的文本块。
1: using S
3: namespace Artech.CodeGeneration
class Program
static void Main(string[] args)
3、代码语句块(Statement Block)
代码语句块通过&#Statement#&的形式表示,中间是一段通过相应编程语言编写的程序调用,我们可以通过代码语句快控制文本转化的流程。在上面的代码中,我们通过代码语句块实现对一个数组进行遍历,输出重复的Console.WriteLine(“Hello, {0}”, “Xxx”)语句。
2: foreach(var person in this.InitializePersonList())
Console.Write(&Hello, {0}&,&&#=
person#&&);
4、表达式块(Expression Block)
表达式块以&#=Expression#&的形式表示,通过它之际上动态的解析的字符串表达内嵌到输出的文本中。比如在上面的foreach循环中,每次迭代输出的人名就是通过表达式块的形式定义的(&#=  person#&)
5、类特性块(Class Feature Block)
如果文本转化需要一些比较复杂的逻辑,我们需要写在一个单独的辅助方法中,甚至是定义一些单独的类,我们就是将它们定义在类特性块中。类特性块的表现形式为&#+ FeatureCode #&,对于Hello World模板,得到人名列表的InitializePersonList方法就定义在类特性块中。
public string[] InitializePersonList()
return new string[]{&Foo&,&Bar&,&Baz&};
了解T4模板的“五大块”之后,相信读者对定义在HelloWord.tt中的模板体现的文本转化逻辑应该和清楚了吧。
四、通过T4模板实现从“数据到代码”的转变
现在我们来完成我们开篇布置得任务:如何将一个已知结构的表示消息列表的XML转换成C#代码,使得我们可以一强类型的编程方式获取和格式化相应的消息条目。我们的T4模板定义如下
1: &#@ template debug=&false& hostspecific=&true& language=&C#& #&
2: &#@ assembly name=&System.Core.dll& #&
3: &#@ assembly name=&System.Xml& #&
4: &#@ import namespace=&System& #&
5: &#@ import namespace=&System.Xml& #&
6: &#@ import namespace=&System.Linq& #&
7: &#@ output extension=&.cs& #&
9: namespace MessageCodeGenrator
public static class Messages
XmlDocument messageDoc = new XmlDocument();
messageDoc.Load(this.Host.ResolvePath(&Messages.xml&));
var messageEntries = messageDoc.GetElementsByTagName(&message&).Cast&XmlElement&();
var categories = (from element in messageEntries
select element.Attributes[&category&].Value).Distinct();
foreach (var category in categories)
23: public
static class &#=
category#&
foreach (var element in messageDoc.GetElementsByTagName(&message&).Cast&XmlElement&().Where(element =& element.Attributes[&category&].Value == category))
= element.Attributes[&id&].V
string value
= element.Attributes[&value&].V
string categotry
= element.Attributes[&category&].V
32: public static MessageEntry &#= id #& = new MessageEntry(&&#= id #&&,&&#=
value#&&,&&#=
categotry#&&);
模板体现出来的转化流程就是:加载XML文件(Messages.xml),然后获取所有的消息类别,为每个消息类别创建一个内嵌于静态类Messages中的以类别命名的类。然后遍历每个类别下的所有消息条目,定义类型为MessageEntry的静态熟悉。
在这里有一点需要特别指出的是:整个代码生成的输入,即XML文件Messages.xml和模板文件位于相同的目录下,但是我们需要通过Host属性的ResolvePath方法去解析文件的物理路径。对ResolvePath方法的调用,需要模板&#@ template …#&指令中的hostspecific设置为true。
1: &#@ template debug=&false& hostspecific=&true& language=&C#& #&
五、T4的文本转化的实现
和我之前采用的代码生成方式(CodeDOM+Custom Tool)一样,对于T4模板的代码生成,VS最终还是通过Custom Tool来完成的。如果你查看TT文件的属性,你会发现Custom Tool会自动设置成:TextTemplatingFileGenerator。
当TextTemplatingFileGenerator被触发后(修改后的文件被保存,或者认为执行Custom Tool),会通过T4引擎完成文本的转换和输出工作。具体来讲,T4引擎的文本转化和输出机制可以通过下图来表示。T4引擎首先对模板的静态内容和动态内容进行解析,最终生成一个继承自的类,所有的文本转化逻辑被放入被重写的Transformation方法中。然后动态创建该对象,执行该方法并将最终的类型以附加文件的形式输出来。
阅读(...) 评论()评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
第一章 java (基础)
第二章 java(高级)

我要回帖

更多关于 hello world java 的文章

 

随机推荐