2016-11-18 3 views
6

구조체 NativePtr의 멤버에 액세스하여 값을 할당하는 방법이 있습니까? 아래 예제에서와 같은 방법으로 할 수 있습니까? 현재 내가 NativePtr.write의 사용을 만들고있어F # 포인터 멤버 접근 자

CoOrds* p = &home; p -> x = 25;

(MSDN에서)

그러나 나는 이것이 가장 좋은/올바른 해결책인지 확실 해요.

감사합니다.

+1

'NativePtr '이 있고이'struct '의 명명 된 요소를 설정 하시겠습니까? F #에서 이것을 달성하기 위해 현재'NativePtr.write '를 어떻게 사용하고 있는지 보여주는 예가 있습니까? –

+2

맞습니다. 나는 업데이트하고자하는 값을 취하는 함수를 만들었고, NativePtr과 그 포인터의 참조 해제 된 구조체는 'NativePtr.write ptr p'입니다. 'NativePtr.write '를 호출하기 전에'p' 구조체 내에서 멤버를 업데이트했습니다. –

답변

4

이렇게 설명하는 방식이 가장 명확합니다.이 방법으로 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 

나는 그것을에 관해서는 열린 질문을 남겨 무엇 가장 좋은 이러한 상황을 다루는 방법은, 그들이 전혀 처리 해야하는 경우입니다. 나는 추가적인 메모리 사용을 희생시키면서 가장 깨끗한 방법으로 첫 번째로 가고 싶다. 마지막으로 임의의 오프셋 방법을 피하는 것이 좋습니다. 원시 오프셋을 추가해야하는 경우 두 번째 방법과 같이보다 쉽게 ​​검증 할 수있는 함수로 둘러싸 기 때문에 호출자가 오프셋을 계산할 필요가 없습니다 그 자체.

+0

위대한 답변, Jake에게 감사드립니다. –