NativePtr.get
и set
функции чтения и записи со смещением. Если вам нужно прочитать байты по байт, используйте это. Если вам нужно читать с нулевым нулевым значением, вместо этого вы можете использовать read
и write
, они будут немного более результативными.
Оператор для взятия «необработанного» адреса (в отличие от ссылки byref<_>
) называется &&
(see definition).
Но есть еще некоторые хитрости участвуют, например: вы должны пометить переменную mutable
, прежде чем взять его адрес, вы не можете просто хранить значение nativeptr<_>
, вам нужно преобразовать его в nativeint
, плюс nativeptr<_>
значения сильно типизированных, так что вам нужно преобразовать между ними через nativeint
и т.д.
следующий фрагмент кода будет делать эквивалент вашей C# код (шаг за шагом и с полными аннотациями типа для повышенной четкости):
open FSharp.NativeInterop
let Main() =
let mutable x: float = 3.1415
let floatPtr: nativeint = NativePtr.toNativeInt<float> &&x
let intPtr: nativeptr<int> = floatPtr |> NativePtr.ofNativeInt<int>
let asInt: int = NativeInterop.NativePtr.read intPtr
asInt
Или более компактный v ersion:
open FSharp.NativeInterop
let Main() =
let mutable x = 3.1415
&&x |> NativePtr.toNativeInt |> NativePtr.ofNativeInt |> NativePtr.read<int>
Или упаковать его для повторного использования:
// val inline readAs : x:'a -> 'b when 'a : unmanaged and 'b : unmanaged
let inline readAs (x: 'a) : 'b =
let mutable x' = x
&&x' |> NativePtr.toNativeInt |> NativePtr.ofNativeInt |> NativePtr.read<'b>
let Main() =
let i = readAs 3.1415 : int
()
Сказав все вышесказанное, я полностью согласен с Джоном Палмером и GuyCoder: , пожалуйста, не делайте этого, если вообще возможно. Это похоже на то, что преждевременная оптимизация, о которой предупредил нас доктор Кнут.
@GuyCoder: Я хочу посмотреть * бит * существующего поплавка, как если бы это был int. – kkm
Какова цель этого? Это, безусловно, плохая идея написать такой код. –
@JohnPalmer: Это совершенно не относится к вопросу, но намерение - хеширование. – kkm