Вопрос

Я хотел бы знать, возможно ли в F#, чтобы объявить тип:

nativeptr<unit>

Это кажется невозможным (компилятор жалуется с «Общая конструкция требует, чтобы тип« единица » - это неуправляемый тип») Есть ли обходной путь, который я мог бы использовать?

Конечная цель состоит в том, чтобы объявить мой собственный BlitDelegate для разоблачения оплота OpCode 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)

Это приводит к ошибке времени выполнения в Blit (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 с некоторыми помощниками для выполнения арифметики на указателе. Поскольку у вас вряд ли будет множество unitS, я не вижу, как это на самом деле помогает вам. Возможно, если вы покажете больше своего кода, будет легче дать более удовлетворительный ответ.

РЕДАКТИРОВАТЬ

Я думаю, что у тебя все правильно. Однако анонимно размещен DynamicMethodS должен быть проверенным, и cpblk Opcode никогда не поддается проверке. Попробуйте использовать другой конструктор для DynamicMethod размещать его на типе или модуле.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top