c# - F# 指针成员访问器

标签 c# .net f# interop pinvoke

有没有什么方法可以访问 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> 的严格类型化type 意味着您不能简单地转换为相关的指针类型。 NativePtr.set offset ptr函数添加 sizeof<'T> * offset ,所以这在这种情况下也没有用。

假设类型 myStructurePacked属性,为简单起见。 a 的偏移量为 0 , 4 表示 b .抛开所有谨慎,完全放弃托管内存领域,我们可以做:

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

关于处理这些情况的最佳方法是什么,我留下了一个悬而未决的问题,如果它们必须被处理的话。我倾向于使用第一种最清晰的方法,但要以额外的内存使用为代价。最后,要不惜一切代价避免使用任意偏移方法——如果你必须处理添加原始偏移,最好将它们包装在一个更容易验证的函数中,如第二种方法,这样调用者就不需要计算偏移本身。

关于c# - F# 指针成员访问器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40685519/

相关文章:

c# - 波兰语符号规则添加 "in"和逻辑运算符

c# - 使用 Dapper C# 在 MySQL 命令中使用变量

c# - 显示数据库中的数据

c# - 使用 HttpClient 时记录请求/响应消息

.net - 最小起订量 - 好的示例应用程序

c# - .NET 库的异常处理模式 - 处理、无人值守还是重新抛出?

c# - String.Equals 和运算符 == 之间的无限调用循环

f# - "as"和指定类型的冒号之间的区别?

reflection - 如何在不实际硬编码路径的情况下确定记录中字段的 json 路径?

f# - 了解 F# 尾递归