Frage

Ich würde gerne wissen, ob es in F# möglich ist, den Typ zu deklarieren:

nativeptr<unit>

Dies scheint nicht möglich (Compiler beschwert sich mit "Ein generisches Konstrukt erfordert, dass der Typ" Einheit "ein nicht verwalteter Typ ist"). Gibt es eine Problemumgehung, die ich verwenden könnte?

Das ultimative Ziel ist es, mein eigenes Blitdelegate für die Enthüllung des Opcode zu deklarieren Cpblk zu einigen meiner F# Code.

Vielen Dank.

Bearbeiten:

Folgendes habe ich auf der Grundlage von KVBs Antwort versucht:

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)

Dann nenne ich diesen Code von einem Klassenmitglied wie diesem:

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)

Dies führt zu einem Laufzeitfehler bei Blit (System.Security.VerificationException: Der Betrieb könnte die Laufzeit destabilisieren.)

Der kommentierte Code funktioniert gut (und kann gefunden werden hier) Aber mein Punkt war es, es in F# zu codieren (nicht C#).

Der Grund, warum ich zunächst benutzen wollte a nativeptr<unit> ist, dass es tatsächlich der Typ der beiden ersten Argumente von ist MemCpy Delegierter (das passt zu void* Typ) und wollte es etwas nachahmen.

Edit2:

Basierend auf der Bearbeitung von KVB habe ich meinen Code geändert, um die Erstellung der Delegierten in einem Typ mit statischen Mitgliedern (wie der C# -Version) zu hosten, und es funktioniert jetzt. Ich benutze die Version nicht mit der nicht verwalteten Einschränkung, aber diese, da ich tatsächlich ein Array von Strukturen blocken muss:

type blitDelegate = delegate of nativeint * nativeint * uint32 -> unit
War es hilfreich?

Lösung

Aus Ihrer Beschreibung ist mir nicht klar nativeptr<unit>. Im Wesentlichen, nativeptr<'t> ist nur ein dünner Wrapper vorbei nativeint Mit einigen Helfern für die Arithmetik auf dem Zeiger. Da es unwahrscheinlich ist, dass Sie eine Reihe von einer Reihe haben unitS, ich sehe nicht, wie das dir tatsächlich hilft. Wenn Sie mehr von Ihrem Code zeigen, ist es vielleicht einfacher, eine zufriedenstellendere Antwort zu geben.

BEARBEITEN

Ich denke, du machst fast alles richtig. Anonym hostete jedoch DynamicMethods muss überprüfbar sein und die cpblk Opcode ist niemals überprüfbar. Versuchen Sie einen anderen Konstruktor für DynamicMethod So hosten Sie es auf einem Typ oder einem Modul.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top