F # Marshal.SizeOf exception including an array of enumerations inside a structure

I encounter a run-time exception including Marshal.SizeOfone that I don't understand. After removing a lot of code, I came up with a small example demonstrating the problem:

#nowarn "9"

open System.Runtime.InteropServices

type Gray = | Black = 0 | Gray = 1 | White = 2

[<Struct; StructLayout(LayoutKind.Sequential, Pack = 1)>]
type GrayStruct =
    [<MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)>]
    val mutable Triple: Gray[]

type Color = | Red = 0 | Green = 1 | Blue = 2

[<Struct; StructLayout(LayoutKind.Sequential, Pack = 1)>]
type ColorStruct =
    [<MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)>]
    val mutable Triple: Color[]

let colorStructToUnit (colorStruct: ColorStruct) = ()

printfn "%A" (Marshal.SizeOf(typeof<GrayStruct>))
printfn "%A" (Marshal.SizeOf(typeof<ColorStruct>))

Running this example with fsi.exe (version 4.1) results in:

12
System.ArgumentException: Type 'FSI_0001+ColorStruct' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.
   at System.Runtime.InteropServices.Marshal.SizeOfHelper(Type t, Boolean throwIfNotMarshalable)
   at System.Runtime.InteropServices.Marshal.SizeOf(Type t)
   at <StartupCode$FSI_0001>.$FSI_0001.main@() in 
C:\f#\Example\example.fsx:line 21
Stopped due to error

Note the similarities between GrayStructand ColorStruct, but Marshal.SizeOfthrottles on ColorStruct. Marshal.SizeOfseems to throw an exception due to the existence of the function colorStructToUnit. If this function is removed, the output will look like this:

12
12

Also, if I save the function colorStructToUnit, but replace:

    val mutable Triple: Color[]

from:

    val mutable Triple: int[]

then the output will also be:

12
12

Thank you for your understanding in this issue.


, , DLL PInvoke. -, . (.. int[] Color[]), , . ?

+6

All Articles