Dichiarare la tipo nativeptr
Domanda
Mi piacerebbe sapere se è possibile in F # per dichiarare il tipo:
nativeptr<unit>
Questo sembra impossibile (compilatore si lamenta con "Un costrutto generica richiede che il tipo di 'unità' è un tipo non gestito" ). C'è una soluzione che potrei usare?
L'obiettivo finale è quello di dichiarare la mia blitDelegate per esporre il Cpblk
codice operativo per alcuni dei miei codice F #.
Grazie.
Modifica
Ecco che cosa ho provato in base alla risposta del 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)
Poi ho chiamato questo codice da un membro della classe del genere:
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)
Il risultato è un errore di runtime a blit ( System.Security.VerificationException:. Operazione potrebbe destabilizzare il runtime )
Il codice commentato funziona bene (e può essere trovato qui ), ma il mio punto è stato quello di codice in F # (non C #).
Il motivo per cui ho voluto utilizzare in un primo momento un nativeptr<unit>
è che è in realtà il tipo dei due primi argomenti di MemCpy
delegato (che le partite di tipo void*
) e un po 'voleva che imitare.
Edit2:
In base a modificare di KVB, ho modificato il mio codice all'host la creazione delegato in un tipo con i membri statici (come la versione C #) e funziona ora. Io non uso la versione con il vincolo non gestito ma questo, dal momento che in realtà bisogno di gamma blit di struct:
type blitDelegate = delegate of nativeint * nativeint * uint32 -> unit
Soluzione
Dalla tua descrizione, non è chiaro per me perché vuoi un nativeptr<unit>
. In sostanza, nativeptr<'t>
è solo un involucro sottile sopra nativeint
con alcuni aiutanti per fare l'aritmetica sul puntatore. Dal momento che è improbabile che avere una serie di unit
s, non vedo come questo in realtà ti aiuta, però. Forse, se si mostra più del vostro codice sarà più facile dare una risposta più soddisfacente.
Modifica
Credo che stai facendo quasi tutto a destra. Tuttavia, DynamicMethod
s anonima ospitati devono essere verificabili, e il codice operativo cpblk
non è mai verificabile. Provare a utilizzare un costruttore diverso per DynamicMethod
di ospitarlo su un tipo o di un modulo.