Declarar el tipo nativeptr
Pregunta
Me gustaría saber si es posible en C # para declarar el tipo:
nativeptr<unit>
Esto no parece posible (compilador se queja con "Un constructo genérico requiere que la 'unidad' tipo es un tipo no administrado" ). ¿Hay una solución alternativa que pueda usar?
El objetivo final es declarar mi propia blitDelegate para exponer el código de operación Cpblk
a algunos de mi F # código.
Gracias.
Editar
Esto es lo que he tratado basado en la respuesta de 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)
Luego me llaman a este código de un miembro de la clase de esa manera:
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)
Esto resulta en un error de ejecución en blit ( System.Security.VerificationException:. Operación podría desestabilizar el tiempo de ejecución )
El código comentado funciona bien (y se puede encontrar aquí ) pero mi objetivo era código en C # (no C #).
La razón por la que quería utilizar en un principio un nativeptr<unit>
es que es en realidad el tipo de los dos primeros argumentos del delegado MemCpy
(que partidos void*
tipo) y algo que quería imitar.
Edit2:
Sobre la base de edición de kvb, que modifica el código para la creación de acogida delegado en un tipo usando los miembros estáticos (como la versión C #) y ahora funciona. Yo no uso la versión con la limitación de no administrado pero éste, ya que en realidad necesito variedad de estructuras blit:
type blitDelegate = delegate of nativeint * nativeint * uint32 -> unit
Solución
A partir de su descripción, no es claro por qué desea un nativeptr<unit>
. Esencialmente, nativeptr<'t>
es sólo un envoltorio fino sobre nativeint
con algunos ayudantes para hacer aritmética en el puntero. Dado que es poco probable que tenga un conjunto de unit
s, no veo cómo esto realmente le ayuda, sin embargo. Tal vez si muestra más de su código será más fácil dar una respuesta más satisfactoria.
Editar
creo que está haciendo casi todo bien. Sin embargo, DynamicMethod
s anónima alojados deben ser verificables, y el código de operación cpblk
nunca es verificable. Trate de usar un constructor diferente para DynamicMethod
a alojarlo en un tipo o módulo.