Функции NativePtr.get
и set
читают и записывают со смещением. Если вам нужно читать байт за байтом, используйте это. Если вам нужно читать с нулевым смещением, вы можете вместо этого использовать read
и write
, они будут немного более производительными.
Оператор для получения «сырого» адреса (в отличие от ссылки byref<_>
) называется &&
(см. определение).
Но есть еще некоторые хитрости, такие как: вам нужно пометить переменную 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
Или более компактный вариант:
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
()
Сказав все вышесказанное, я полностью согласен с Джоном Палмером и ГайКодером: пожалуйста, не делайте этого, если это вообще возможно. Это похоже на преждевременную оптимизацию, о которой нас предупреждал доктор Кнут.
person
Fyodor Soikin
schedule
22.03.2016
NativePtr.get
правильной заменой C#*
, когда'T
является примитивным типом значения? Я понятия не имею, что такоеldobj
. - person kkm   schedule 23.03.2016Bitconverter
естьDoubleToInt64Bits
(который мне не нужен), но нетSingleToInt32Bits
(который мне нужен, и который не более чем*((int*)&value
. Еще глупее было бы создать отдельную библиотеку C# только для этой единственной функции! - person kkm   schedule 23.03.2016ldobj
. Вы всегда можете проверить это с целыми числами / байтами / чем-то простым или даже написать программу сравнения для сравнения с C. Сказав это,get
довольно разработан, чтобы притворяться, что ptr указывает на массив. - person John Palmer   schedule 23.03.2016&
. Без него я могу стрелять только случайными адресами сNativePtr.get
:) - person kkm   schedule 23.03.2016&
и*
все еще другое. Так что нет, не дубликат. - person kkm   schedule 23.03.2016