bug*_*der 6 enums f# struct sizeof marshalling
我遇到了涉及Marshal.SizeOf
我不理解的运行时异常.在删除了大量代码之后,我想出了一个演示该问题的小例子:
#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>))
Run Code Online (Sandbox Code Playgroud)
使用fsi.exe(版本4.1)运行此示例会导致:
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
Run Code Online (Sandbox Code Playgroud)
注意之间的相似GrayStruct
和ColorStruct
,但Marshal.SizeOf
扼流圈ColorStruct
.Marshal.SizeOf
似乎因为colorStructToUnit
函数的存在而抛出异常.如果删除该功能,输出将变为:
12
12
Run Code Online (Sandbox Code Playgroud)
另外,如果我保留该colorStructToUnit
功能,但替换:
val mutable Triple: Color[]
Run Code Online (Sandbox Code Playgroud)
有:
val mutable Triple: int[]
Run Code Online (Sandbox Code Playgroud)
然后输出也变成:
12
12
Run Code Online (Sandbox Code Playgroud)
感谢您对此问题的任何见解.
请注意,我在更大的代码库中遇到此问题,该代码库尝试通过PInvoke与旧DLL进行交互.此问题似乎只影响结构中的枚举数组.一种解决方法是封装底层类型(即int[]
代替Color[]
),然后将这些值转换为枚举,但该解决方案需要对几乎相同结构的多个定义.是否有更优雅的方法来克服这个问题?