Skip to content

Instantly share code, notes, and snippets.

@zpodlovics
Created February 26, 2015 18:48
Show Gist options
  • Save zpodlovics/848f3c13928dfe1b0d00 to your computer and use it in GitHub Desktop.
Save zpodlovics/848f3c13928dfe1b0d00 to your computer and use it in GitHub Desktop.
// Author: Zoltan Podlovics
// License: Apache License, Version 2.0, https://www.apache.org/licenses/
// Description: Proof of concept demo of FSharp on struct field UOM.
// After commenting source of compilation error in the main,
// "let (s2: S2) = readPtr ptr"
// the generated bytecode show no differences between the S1 and S2 struct
// representation the uom type easure works as expected.
//
// Usage:
// fsharpc structuomunmanaged.fs
//
// Error message:
// FS0001: A generic construct requires that the type 'S2' is an unmanaged type
#nowarn "9"
open System.Runtime.InteropServices
open Microsoft.FSharp.NativeInterop
[<Measure>]
type Version
[<NoComparison;NoEquality>]
[<Struct>]
type S1 =
val i: int64
val v: int64
[<NoComparison;NoEquality>]
[<Struct>]
type S2 =
val i: int64
val v: int64<Version>
[<Unverifiable>]
let readPtr (b: nativeptr<byte>): 'T when 'T: unmanaged and 'T: struct =
let iPtr = NativePtr.toNativeInt b in
let tPtr = NativePtr.ofNativeInt<'T> iPtr in
NativePtr.read tPtr
[<EntryPoint>]
let main (args : string[]) =
let (buffer: byte array) = Array.zeroCreate 64
let handle = GCHandle.Alloc(buffer, GCHandleType.Pinned) in
let ptr = handle.AddrOfPinnedObject() |> NativePtr.ofNativeInt<byte>
let (s1: S1) = readPtr ptr
let (s2: S2) = readPtr ptr
//return
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment