【发布时间】:2010-12-28 19:40:03
【问题描述】:
我想知道是否可以在 F# 中声明类型:
nativeptr<unit>
这似乎是不可能的(编译器抱怨 “泛型构造要求类型 'unit' 是非托管类型”)。有没有我可以使用的解决方法?
最终目标是声明我自己的 blitDelegate,以便将操作码 Cpblk 暴露给我的一些 F# 代码。
谢谢。
编辑:
这是我根据 kvb 的回答尝试过的:
type blitDelegate<'T when 'T : unmanaged> = delegate of nativeptr<'T> * nativeptr<'T> * uint32 -> unit
let createBlitDelegate<'T when 'T : unmanaged>() =
let dm = new DynamicMethod("blit",
typeof<System.Void>,
[| typeof<nativeptr<'T>>; typeof<nativeptr<'T>>; typeof<uint32> |])
let ilGenerator = dm.GetILGenerator()
ilGenerator.Emit(OpCodes.Ldarg_0)
ilGenerator.Emit(OpCodes.Ldarg_1)
ilGenerator.Emit(OpCodes.Ldarg_2)
ilGenerator.Emit(OpCodes.Cpblk)
ilGenerator.Emit(OpCodes.Ret)
dm.CreateDelegate(typeof<blitDelegate<'T>>) :?> blitDelegate<'T>
let blit (blitDel:blitDelegate<'T>) dst src byteWidth = blitDel.Invoke(dst, src, byteWidth)
然后我像这样从类成员中调用此代码:
let dst = //get nativeint destination address
let src = //get nativeint source address
let bd = createBlitDelegate<'T>()
let tdst = NativePtr.ofNativeInt<'T> dst
let tsrc = NativePtr.ofNativeInt<'T> src
do blit bd tdst tsrc (uint32 size)
//Program.MemCpy.Invoke(dst.ToPointer(), dst.ToPointer(), uint32 size)
这会导致 blit 出现运行时错误(System.Security.VerificationException:操作可能会破坏运行时。)
注释代码运行良好(可以在 here 找到),但我的意思是用 F#(不是 C#)对其进行编码。
我一开始想使用nativeptr<unit>的原因是它实际上是MemCpy委托的两个第一个参数的类型(匹配void*类型)并且有点想模仿它。
编辑2:
基于 kvb 的编辑,我修改了代码以使用静态成员(如 C# 版本)在类型中托管委托创建,现在它可以工作了。 我不使用具有非托管约束的版本,而是使用这个版本,因为我实际上需要 blit 结构数组:
type blitDelegate = delegate of nativeint * nativeint * uint32 -> unit
【问题讨论】:
标签: f# interop native c#-to-f# unit-type