F# 指针成员访问器
F# pointer member accessor
有没有什么方法可以访问 NativePtr
结构的成员并为它们赋值,就像在下面的示例中使用 C# 一样?
(来自 MSDN)
CoOrds* p = &home;
p -> x = 25;
目前我正在使用 NativePtr.write
,但是我不确定这是否是 best/correct 解决方案。
谢谢。
假设您必须以这种方式处理 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
结构的成员并为它们赋值,就像在下面的示例中使用 C# 一样?
(来自 MSDN)
CoOrds* p = &home;
p -> x = 25;
目前我正在使用 NativePtr.write
,但是我不确定这是否是 best/correct 解决方案。
谢谢。
假设您必须以这种方式处理 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
我留下一个悬而未决的问题,即如果必须处理这些情况,最好的 方法是什么。我倾向于使用第一种最清晰的方法,但要以额外的内存使用为代价。最后,要不惜一切代价避免使用任意偏移方法——如果你必须处理添加原始偏移,最好将它们包装在一个更容易验证的函数中,如第二种方法,这样调用者就不需要计算偏移本身。