首页 > 代码库 > 使用内联中间语言

使用内联中间语言

使用内联中间语言(Inline IL)

 

内联中间语言(Inline IL)能够直接在中间语言(intermediate language,IL)中定义函数体,中间语言是 F# 编译后的语言,它主要为语言添加了实现特定低级运算符和函数,比如,加法和box 和 not 的功能。我们很少会用到这个功能,因为F# 库FSharp.Core.dll 已经公开了所有的、可能需要的生成中间语言的功能。然而,有一些极为罕见的情况,不能在 F# 中完成,而只能在中间语言中实现,内联中间语言是很好的选择。

使用内联中间语言很简单,只要把中间语言指令放在括号和#号中间,(# #)。中间语言指令放在字符串中间,使用能够被ilasm.exe 编译的标准记号,它必须是正确的中间语言形式,否则会编译出错;然后,传递参数给中间语言指令,它们被压入中间语言评估栈(IL evaluation stack)中;还必须使用标准的冒号,告诉编译器返回的类型是什么,这要放在括号中间;还需要显式地指定参数类型,因为编译器没有办法出它们的类型。

我们现在看一下使用内联中间语言的示例。假设由于某种原因,我们要使用在 F# 基本库fslib.dll 中定义的加法和减法运算符,用我们自己定义的函数去替换它们。我们定义了两个函数add 和 sub,函数体使用中间语言定义:

 

// declare add functionusing the IL add instruction

let add (x:int)(y:int) = (#"add"x y : int #)

// declare sub functionusing the IL sub instruction

let sub (x:int)(y:int) = (#"sub"x y : int #)

 

// test these functions

let x = add 1 1

let y = sub 4 2

 

// print the results

printfn "x: %i y:%i" x y

 

示例的运行结果如下:

 

x: 2 y: 2

 

程序员应该小心使用这种方法,因为写一个毫无意义的程序并不重要,编译器不可能为此而发出警告。考虑下面的的程序,我们修改了一下前面的示例,把 "add" 指令替换成 "ret" 指令,表示是返回值,在这个上下文中没有意义。这个示例在编译时没有错误和警告,但是运行时会出错。

 

// create a faulty add function

let add (x:int) (y:int) = (#"ret"x y : int #)

 

// attempt to use fault function

let x = add 1 1

 

示例的运行结果如下:

 

Unhandled Exception: System.InvalidProgramException:Common Language Runtime

detected an invalid program.

at Error.add(Int32 x, Int32 y)

 

注意

随.NET SDK 发布的一个工具能够帮助检测这种错误,这个工具叫peverify.exe,更多有关这个工具的信息,参见http://msdn2.microsoft.com/en-us/library/62bwd2yd(vs.80).aspx。