call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}
//main函数(主函数),注意这是一个全局方法。
.method assembly static int32 main(class System.String args)
{
……
}
……
//RealMath类的Add方法,注意这是一个全局方法,使用PInvoke(平台调用)调用本机代码实现。
.method public static pinvokeimpl(/* No map */) modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall) float64 RealMath.Add(modopt([mscorlib]System.Runtime.CompilerServices.IsConst) modopt([mscorlib]System.Runtime.CompilerServices.IsConst) value class RealMath*, float64, float64) native unmanaged
{
}
//RealMath类的Minus方法,注意这是一个全局方法,使用PInvoke(平台调用)调用本机代码实现。
.method public static pinvokeimpl(/* No map */) modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall) float64 RealMath.Minus(modopt([mscorlib]System.Runtime.CompilerServices.IsConst) modopt([mscorlib]System.Runtime.CompilerServices.IsConst) value class RealMath*, float64, float64) native unmanaged
{
}
……
读者读到这里可能会感到有些奇怪:不是说.NET编程语言(例如C#)源程序完全由类构成吗?那么编译后生成的可执行文件反汇编后,就不应该还有全局方法(函数),为什么反汇编结果中竟然出现了全局方法呢?
实际上,.NET CLI的第2部分“元数据的定义和语义”中已经明确说明:字段和方法都可以是全局的,也就是不在任何一个类型中定义,而在模块(Module)中直接定义的字段和方法。
虽然C#等.NET编程语言不一定支持全局字段和全局方法,但是C++/CLI是支持全局字段和全局方法的,C++/CLI中的C++全局变量和全局函数,就是使用全局字段和全局方法实现的。
其实,说.NET编程语言源程序中完全没有全局字段和全局方法,这种说法本身就是不太合理的,类型中的静态成员,包括静态字段和静态方法,本质上不也就相当于加了类型名“名字空间”——相当于“前缀”的全局字段和全局方法吗?
C++语言特性明显不同于C#,C++/CLI仍然支持C++语言特性。例如:在C#中,使用struct关键字定义的结构属于.NET CTS值类型,使用class关键字定义的类属于.NET CTS引用类型,但是在C++/CLI中,struct关键字和class关键字是等价的,区别只是使用struct关键字定义的类中,成员默认是public的,而使用class关键字定义的类中,成员默认是private的。
回到上述反汇编结果,从反汇编结果中,可以明显看出以下几点:
1、C++/CLI中直接使用class或者struct关键字定义类,并不是直接定义.NET CTS中的类型。C++/CLI中定义.NET CTS中的类型,自定义值类型必须使用value class或者value struct关键字定义,自定义引用类型必须使用ref class或者ref struct关键字定义。
2、对于C++/CLI中的C++类,也就是直接使用class或者struct关键字定义的类,其实现方法,包括类的对象的实现方法,仍然与传统C++实现类和对象的方法相似:对象的属性(字段或者成员变量)和方法(成员函数)分离,对象设计成包含对象属性的数据结构,方法设计成针对对象属性的过程(函数),将包含对象