简体   繁体   中英

F# pointer member accessor

Is there any way of accessing the members of a NativePtr struct and assigning a value to them, much in the same way that you can in C# in the below example?

(From MSDN)

CoOrds* p = &home; p -> x = 25;

Currently I'm making use of NativePtr.write , however I'm unsure whether this is the best/correct solution.

Thanks.

The way you described is the clearest way of doing this, presuming that you must deal with the struct s in this manner. For completeness' sake, here's that method (with the implementation details of the packing omitted):

open FSharp.NativeInterop

[<StructLayout(...)>]
type myStructure =
    struct
        val mutable a : int
        val mutable b : byte
    end

let changeA pointer newA =
    let mutable structure = NativePtr.read pointer
    structure.a <- newA
    NativePtr.write pointer structure

However, because you must know the exact offsets of each of the elements, you could also use this information to write directly to that field. F# does not provide a way of doing this using named identifiers, and its strict typing of the nativeptr<'T> type means that you cannot simply cast to the relevant pointer type. The NativePtr.set offset ptr function adds sizeof<'T> * offset , so this is also no use in this case.

Let's say the type myStructure has the Packed attribute, for simplicity. The offsets are then 0 for a , and 4 for b . Throwing all caution to the wind, and completely abandoning the realm of managed memory, we could do:

let changeB pointer newB =
    let bPtr =
        NativePtr.toNativeInt pointer
        |> (+) 4n
        |> NativePtr.ofNativeInt<byte>
    NativePtr.write bPtr newB

or even:

let changeMember pointer offset (value : 'T) =
    let pointer' =
        NativePtr.toNativeInt pointer
        |> (+) (nativeint offset)
        |> NativePtr.ofNativeInt<'T>
    NativePtr.write pointer' value

I leave it an open question as to what the best method of dealing with these situations is, if they must be dealt with at all. I am inclined to go with the first, clearest method at the expense of additional memory use. The last, arbitrary offset method is to be avoided at all costs - if you must deal with adding raw offsets, it is much much better to wrap them in a more easily verifiable function like the second method, so the caller need not calculate the offset itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM