Reflection.Emit不安全代码

3

我正在使用F#中的Reflection Emit进行一些黑客技术。我试图做与此C#代码相当的事情:

var ass = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.RunAndSave);
var mb = ass.DefineDynamicModule("Test", "Test.dll", false);
var t = mb.DefineType("Foo", TypeAttributes.Public, typeof(ValueType));
t.DefineField("foo", typeof(int*), FieldAttributes.Public);
t.CreateType();
ass.Save("Test.dll");

其中特别的一行是definefield行。在F#中,我能找到的最接近的是

let f = t.DefineField("foo", (typeof<nativeptr<int>>), FieldAttributes.Public)

然而,最终编译的字段编译成了IntPtr类型,而不是int*类型。(请注意,对于nativeint或任何其他类型,它都是IntPtr类型)
此外,我希望能够在程序中定义一个结构体,并在另一个结构体中使用Foo*,但显然在这种情况下(无论是在C#还是F#中),我都无法使用typeof。是否有一种方法可以从Type/TypeBuilder中将字段定义为Foo*?
在任何人指出这可能都是疯狂的(我也同意)之前,这是一个有趣的项目,我要找出自己可以生成多疯狂的代码,而C#可能不会让我这么做 :)
1个回答

4

这对第一种情况非常有效: let f = t.DefineField("foo", (typeof<ilsigptr<int>>), FieldAttributes.Public)谢谢! - neil danson
对于第二种情况:当使用MakeGenericType时,它会针对ilsigptr推断出一个无效操作异常,而对于let p = typedefof>.MakeGenericType([|t :> Type|]) let f = t.DefineField("rec", p, FieldAttributes.Public)则运行良好。我猜测ilsigptr有一些特殊之处,但是如果能够访问生成的结构体指针将会很棒。您有什么想法吗? - neil danson
1
实际上,你可以这样做,适用于所有情况: let p = t.MakePointerType() let f = t.DefineField("rec", p, FieldAttributes.Public)谢谢你的帮助,Daniel。我将其标记为答案,因为它是正确方向上的重要“指针”。 - neil danson
啊,太简单了。很高兴你解决了它。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接