声明本机Pttr 类型
题
我想知道是否有可能在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
有一些帮助者在指针上进行算术。由于您不太可能有一系列 unit
S,不过,我看不出这对您有何帮助。也许,如果您显示更多代码,则更容易给出更令人满意的答案。
编辑
我认为您正在做几乎所有的事情。但是,匿名托管 DynamicMethod
S必须是可验证的,并且 cpblk
OpCode永远无法验证。尝试使用其他构造函数 DynamicMethod
将其托管在类型或模块上。
不隶属于 StackOverflow