我想知道是否有可能在f#中声明类型:

nativeptr<unit>

这似乎是不可能的(编译器抱怨 “通用构造要求'单位'是一种非托管类型”)。我可以使用解决方法吗?

最终目标是声明我自己的闪电战公开码 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)

这会导致闪电时的运行时错误(System.Security.VerificationException:操作可能会破坏运行时的稳定。)

评论的代码运行良好(可以找到 这里)但我的意思是将其编码为f#(不是C#)。

我首先要使用的原因 nativeptr<unit> 是实际上是两个第一个参数的类型 MemCpy 委托(匹配 void* 类型),有点想模仿它。

edit2:

根据KVB的编辑,我修改了代码,以使用静态成员(例如C#版本)在类型中托管代表创建,现在可以使用。我不使用具有不受管理约束的版本,但是这个版本,因为我实际上需要闪闪发光的结构数组:

type blitDelegate = delegate of nativeint * nativeint * uint32 -> unit
有帮助吗?

解决方案

从您的描述来看,我还不清楚为什么您要 nativeptr<unit>. 。本质上, nativeptr<'t> 只是一个薄包装纸 nativeint 有一些帮助者在指针上进行算术。由于您不太可能有一系列 unitS,不过,我看不出这对您有何帮助。也许,如果您显示更多代码,则更容易给出更令人满意的答案。

编辑

我认为您正在做几乎所有的事情。但是,匿名托管 DynamicMethodS必须是可验证的,并且 cpblk OpCode永远无法验证。尝试使用其他构造函数 DynamicMethod 将其托管在类型或模块上。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top