Объявите тип NativePtr
Вопрос
Я хотел бы знать, возможно ли в 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
с некоторыми помощниками для выполнения арифметики на указателе. Поскольку у вас вряд ли будет множество unit
S, я не вижу, как это на самом деле помогает вам. Возможно, если вы покажете больше своего кода, будет легче дать более удовлетворительный ответ.
РЕДАКТИРОВАТЬ
Я думаю, что у тебя все правильно. Однако анонимно размещен DynamicMethod
S должен быть проверенным, и cpblk
Opcode никогда не поддается проверке. Попробуйте использовать другой конструктор для DynamicMethod
размещать его на типе или модуле.