问题描述
如何在已编译的F#程序中从字符串执行F#代码?
How do I execute F# code from a string in a compiled F# program?
推荐答案
下面是一个小脚本,该脚本使用FSharp CodeDom将字符串编译为程序集并将其动态加载到脚本会话中.
Here's a little script that uses the FSharp CodeDom to compile a string into an assembly and dynamically load it into the script session.
它使用类型扩展只是为了允许对参数使用有用的默认值(希望让绑定函数在不久的将来支持可选的,命名的和params参数.)
It uses a type extension simply to allow useful defaults on the arguments (hopefully let bound functions will support optional, named and params arguments in the near future.)
#r "FSharp.Compiler.dll"
#r "FSharp.Compiler.CodeDom.dll"
open System
open System.IO
open System.CodeDom.Compiler
open Microsoft.FSharp.Compiler.CodeDom
let CompileFSharpString(str, assemblies, output) =
use pro = new FSharpCodeProvider()
let opt = CompilerParameters(assemblies, output)
let res = pro.CompileAssemblyFromSource( opt, [|str|] )
if res.Errors.Count = 0 then
Some(FileInfo(res.PathToAssembly))
else None
let (++) v1 v2 = Path.Combine(v1, v2)
let defaultAsms = [|"System.dll"; "FSharp.Core.dll"; "FSharp.Powerpack.dll"|]
let randomFile() = __SOURCE_DIRECTORY__ ++ Path.GetRandomFileName() + ".dll"
type System.CodeDom.Compiler.CodeCompiler with
static member CompileFSharpString (str, ?assemblies, ?output) =
let assemblies = defaultArg assemblies defaultAsms
let output = defaultArg output (randomFile())
CompileFSharpString(str, assemblies, output)
// Our set of library functions.
let library = "
module Temp.Main
let f(x,y) = sin x + cos y
"
// Create the assembly
let fileinfo = CodeCompiler.CompileFSharpString(library)
// Import metadata into the FSharp typechecker
#r "0lb3lphm.del.dll"
let a = Temp.Main.f(0.5 * Math.PI, 0.0) // val a : float = 2.0
// Purely reflective invocation of the function.
let asm = Reflection.Assembly.LoadFrom(fileinfo.Value.FullName)
let mth = asm.GetType("Temp.Main").GetMethod("f")
// Wrap weakly typed function with strong typing.
let f(x,y) = mth.Invoke(null, [|box (x:float); box (y:float)|]) :?> float
let b = f (0.5 * Math.PI, 0.0) // val b : float = 2.0
要在编译的程序中使用此功能,您将需要纯粹的反射调用.
To use this in a compiled program you would need the purely reflective invocation.
与社区中许多人迫切要求的完整脚本API相比,这当然是个玩具.
Of course this is a toy compared to a full scripting API that many of us in the community have urgently requested.
祝你好运
丹尼
这篇关于如何执行在已编译的F#程序的字符串中找到的F#代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!