Я хотел бы знать, возможно ли в F # объявить тип:
nativeptr<unit>
Это кажется невозможным (компилятор жалуется на "Универсальная конструкция требует, чтобы тип 'unit' был неуправляемым типом" ). Есть ли обходной путь, который я мог бы использовать?
Конечная цель - объявить мой собственный blitDelegate для предоставления кода операции 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