有什么办法可以访问NativePtr
结构体的成员并为它们赋值,这与您在下面的示例中可以在C#中使用的方式大致相同?F#指针成员访问器
(从MSDN)
CoOrds* p = &home; p -> x = 25;
目前我正在使用的NativePtr.write
,但是我不能确定这是否是最好的/正确的解决方案。
谢谢。
有什么办法可以访问NativePtr
结构体的成员并为它们赋值,这与您在下面的示例中可以在C#中使用的方式大致相同?F#指针成员访问器
(从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
我离开它一个悬而未决的问题,以如果必须处理这些情况,那么处理这些情况的方法是什么。我倾向于以牺牲更多内存使用为代价的第一个最清晰的方法。最后的任意偏移量方法是不惜一切代价来避免的 - 如果您必须处理添加原始偏移量,则将它们包装在更容易验证的函数(如第二个方法)中要好得多,因此调用者不需要计算偏移量本身。
很好的答案,谢谢杰克。 –
澄清 - 你有一个'NativePtr',你想设置这个'struct'的命名元素?你有没有一个例子说明你如何使用'NativePtr.write'在F#中实现这个功能? –
是的,这是正确的。我创建了一个函数,它接受我希望更新的值,NativePtr和来自该指针的取消引用的结构: 'NativePtr.write ptr p'。 在调用'NativePtr.write'之前,我已经更新了'p'结构中的成员。 –