GPU デバイスでポインターを表す型をコーディングしようとしていますが、get と set のインデックス付きプロパティを使用して、配列のように動作する必要があります。要素の型がプリミティブ型であれば問題ないのですが、構造体を使うとメンバの値を変更できません。
このコードを参照してください:
#nowarn "9"
open System
open System.Runtime.InteropServices
[<Struct;StructLayout(LayoutKind.Sequential)>]
type MyStruct =
val mutable x : int
val mutable y : int
val mutable z : int
override this.ToString() = sprintf "(%d,%d,%d)" this.x this.y this.z
let deviceOnly() = failwith "this function should be used in quotation only"
type DevicePtr<'T>(h:nativeint) =
member this.Handle = h
member this.Item with get (idx:int) : 'T = deviceOnly() and set (idx:int) (value:'T) : unit = deviceOnly()
member this.Reinterpret<'T2>() = DevicePtr<'T2>(h)
member this.Volatile() = DevicePtr<'T>(h)
static member (+) (ptr:DevicePtr<'T>, offset:int) = DevicePtr<'T>(ptr.Handle + nativeint(offset * sizeof<'T>))
let test() =
let mutable test1 = MyStruct()
test1.x <- 1
let foo (collection:MyStruct[]) =
collection.[0].x <- 1
let bar (collection:DevicePtr<MyStruct>) =
collection.[0].x <- 1
//error FS0257:
// Invalid mutation of a constant expression.
// Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.
したがって、型は DevicePtr<'T> であり、get メソッドと set メソッドの両方を持つインデックス付きプロパティ Item があります。しかし、get メソッドは 'T の値を返すだけなので、それを変更することはできません。しかし、システム配列は機能します。
このような経験をしたことがある人はいませんか?配列のように機能する型を作成するには? インデックス付きプロパティの get 関数が、値ではなく変更可能な参照を返すことを願っています。