有什么方法可以访问NativePtr
结构的成员并为其分配值,就像在下面的示例中使用C#一样?
(来自MSDN)CoOrds* p = &home;p -> x = 25;
目前,我正在使用NativePtr.write
,但是我不确定这是否是最佳/正确的解决方案。
谢谢。
最佳答案
假设您必须以这种方式处理struct
,那么您描述的方式是最清晰的方法。为了完整起见,这里是该方法(省略了打包的实现细节):
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
但是,由于必须知道每个元素的确切偏移量,因此也可以使用此信息直接写入该字段。 F#没有提供使用命名标识符执行此操作的方法,并且它严格地键入
nativeptr<'T>
类型意味着您不能简单地转换为相关的指针类型。 NativePtr.set offset ptr
函数添加了sizeof<'T> * offset
,因此在这种情况下也没有用。为了简单起见,假设
myStructure
类型具有Packed
属性。那么,a
的偏移量为0,b
的偏移量为4。我们全力以赴,完全放弃了托管内存的领域,我们可以这样做:let changeB pointer newB =
let bPtr =
NativePtr.toNativeInt pointer
|> (+) 4n
|> NativePtr.ofNativeInt<byte>
NativePtr.write bPtr newB
甚至:
let changeMember pointer offset (value : 'T) =
let pointer' =
NativePtr.toNativeInt pointer
|> (+) (nativeint offset)
|> NativePtr.ofNativeInt<'T>
NativePtr.write pointer' value
对于这些情况的最佳解决方法是什么(如果必须加以处理),则是一个悬而未决的问题。我倾向于采用第一种最清晰的方法,但会占用更多的内存。不惜一切代价避免使用最后一种任意偏移量方法-如果必须处理原始偏移量,最好将它们包装在像第二种方法那样更易于验证的函数中,因此调用者无需计算偏移量本身。