Déclarer la nativeptr Type
Question
Je voudrais savoir s'il est possible en F # pour déclarer le type:
nativeptr<unit>
Cela ne semble pas possible (compilateur se plaint avec « Une construction générique exige que la « unité » de type est un type non géré » ). Y at-il une solution que je pourrais utiliser?
Le but ultime est de déclarer ma propre blitDelegate pour exposer la Cpblk
opcode à certains de mon code F #.
Merci.
Modifier
Voici ce que j'ai essayé basé sur la réponse 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)
Alors j'appeler ce code d'un membre de classe comme ça:
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 en résulte une erreur d'exécution à blit ( System.Security.VerificationException. Opération pourrait déstabiliser le moteur d'exécution )
Le code commenté fonctionne bien (et peut être trouvé ici ) mais mon point est le code dans F # (pas C #).
La raison pour laquelle je voulais utiliser d'abord un nativeptr<unit>
est qu'il est en fait le type des deux premiers arguments de délégué MemCpy
(que les matchs void*
type) et voulait un peu l'imiter.
Edit2:
D'après l'édition de KVB, je modifié mon code pour hôte la création de délégué dans un type utilisant des éléments statiques (comme la version C #) et il fonctionne maintenant. Je n'utilise pas la version avec la contrainte non géré mais celui-ci, puisque je réellement besoin de tableau blit de struct:
type blitDelegate = delegate of nativeint * nativeint * uint32 -> unit
La solution
D'après votre description, il est pas clair pour moi pourquoi vous souhaitez un nativeptr<unit>
. Essentiellement, nativeptr<'t>
est juste une enveloppe mince sur nativeint
avec quelques aides pour effectuer des opérations arithmétiques sur le pointeur. Étant donné que vous avez peu de chances d'avoir un tableau de unit
s, je ne vois pas comment cela vous aide réellement, cependant. Peut-être que si vous montrez plus de votre code, il sera plus facile de donner une réponse plus satisfaisante.
EDIT
Je pense que vous faites presque tout droit. Cependant, de façon anonyme hébergé DynamicMethod
s doivent être vérifiables, et l'opcode cpblk
est jamais vérifiable. Essayez d'utiliser un constructeur différent pour DynamicMethod
l'héberger sur un type ou d'un module.