创建和使用类对象
首先我们定义一个简单的类,它只包含一个方法用于计算一个整数的平方(square),代码如下:
.assembly extern mscorlib {}
.assembly MathLib
{
.ver 1:0:1:0
}
.module MathLib.dll
.namespace HangamaHouse
{
.class public ansi auto MathClass extends [mscorlib]System.Object
{
.method public int32 GetSquare(int32) cil managed
{
.maxstack 3
ldarg.0 // 加载对象的 this 指针到堆栈上
ldarg.1 // 实例方法的实际的参数索引总是从 1 开始
ldarg.1
mul
ret
}
}
}
.assembly MathLib
{
.ver 1:0:1:0
}
.module MathLib.dll
.namespace HangamaHouse
{
.class public ansi auto MathClass extends [mscorlib]System.Object
{
.method public int32 GetSquare(int32) cil managed
{
.maxstack 3
ldarg.0 // 加载对象的 this 指针到堆栈上
ldarg.1 // 实例方法的实际的参数索引总是从 1 开始
ldarg.1
mul
ret
}
}
}
然后用命令 ILAsm MathLib.il /dll 编译为一个 DLL.
调用的范例如下,这里创建了第一个 dll 里面的类对象,并调用其方法。
.assembly extern mscorlib {}
.assembly extern MathLib {.ver 1:0:1:0}
//
//rest code here
//
.method static void Main() cil managed
{
.maxstack 2
.entrypoint
.locals init (valuetype [MathLib]HangamaHouse.MathClass mclass)
ldloca mclass // 加载对象地址
ldc.i4 5 // 方法的参数
call instance int32 [MathLib]HangamaHouse.MathClass::GetSquare(int32)
ldstr "The Square of 5 Returned : "
call void [mscorlib]System.Console::Write(string)
call void [mscorlib]System.Console::WriteLine(int32)
ret
}
.assembly extern MathLib {.ver 1:0:1:0}
//
//rest code here
//
.method static void Main() cil managed
{
.maxstack 2
.entrypoint
.locals init (valuetype [MathLib]HangamaHouse.MathClass mclass)
ldloca mclass // 加载对象地址
ldc.i4 5 // 方法的参数
call instance int32 [MathLib]HangamaHouse.MathClass::GetSquare(int32)
ldstr "The Square of 5 Returned : "
call void [mscorlib]System.Console::Write(string)
call void [mscorlib]System.Console::WriteLine(int32)
ret
}
构造器和属性
构造器是这样定义的:
.class public MathClass extends [mscorlib]System.ValueType
{
.field private int32 mValue
// 其他代码。。
.method public specialname rtspecialname instance void .ctor() cil managed
{
ldarg.0 // 加载 this 指针
ldc.i4.s 15
stfld int32 HangamaHouse.MathClass::mValue // 保存到字段
ret
}
// 其他代码。。
{
.field private int32 mValue
// 其他代码。。
.method public specialname rtspecialname instance void .ctor() cil managed
{
ldarg.0 // 加载 this 指针
ldc.i4.s 15
stfld int32 HangamaHouse.MathClass::mValue // 保存到字段
ret
}
// 其他代码。。
可以看到,构造器实际上是一个叫做 .ctor 的特殊方法。以上代码中使用 specialname 和 rtspecialname 来标注它是一个特殊名称的方法。
在 IL 中,构造器是不会自动被调用的,你必须手工去调用它。下面是一个例子:
.method public static void Main() cil managed
{
.maxstack 2
.entrypoint
.locals init (valuetype [MathLib]HangamaHouse.MathClass mclass)
ldloca mclass
call instance void [MathLib]HangamaHouse.MathClass::.ctor()
{
.maxstack 2
.entrypoint
.locals init (valuetype [MathLib]HangamaHouse.MathClass mclass)
ldloca mclass
call instance void [MathLib]HangamaHouse.MathClass::.ctor()
属性的实现跟构造器类似,实际上也是方法。代码如下:
.method specialname public instance int32 get_Value() cil managed
{
ldarg.0
ldfld int32 HangamaHouse.MathClass::mValue
ret
}
.method specialname public instance void set_Value(int32 ) cil managed
{
ldarg.0
ldarg.1
stfld int32 HangamaHouse.MathClass::mValue
ret
}
//Define the property, Value
.property int32 Value()
{
.get instance int32 get_Value()
.set instance void set_Value(int32 )
}
{
ldarg.0
ldfld int32 HangamaHouse.MathClass::mValue
ret
}
.method specialname public instance void set_Value(int32 ) cil managed
{
ldarg.0
ldarg.1
stfld int32 HangamaHouse.MathClass::mValue
ret
}
//Define the property, Value
.property int32 Value()
{
.get instance int32 get_Value()
.set instance void set_Value(int32 )
}
使用属性其实就是调用以上代码中的 get_Value 和 set_Value 这两个方法:
.maxstack 2 .locals
init (valuetype [MathLib]HangamaHouse.MathClass tclass)
ldloca tclass
ldc.i4 25
call instance void [MathLib]HangamaHouse.MathClass::set_Value(int32)
ldloca tclass
call instance int32 [MathLib]HangamaHouse.MathClass::get_Value()
ldstr "Propert Value Set to : "
call void [mscorlib]System.Console::Write(string)
call void [mscorlib]System.Console::WriteLine(int32)
init (valuetype [MathLib]HangamaHouse.MathClass tclass)
ldloca tclass
ldc.i4 25
call instance void [MathLib]HangamaHouse.MathClass::set_Value(int32)
ldloca tclass
call instance int32 [MathLib]HangamaHouse.MathClass::get_Value()
ldstr "Propert Value Set to : "
call void [mscorlib]System.Console::Write(string)
call void [mscorlib]System.Console::WriteLine(int32)
(To be continued)