簡體   English   中英

包含結構數組的結構的C#聯合

[英]C# Unions of Structs that Contain Arrays of Structs

我正在嘗試創建多個結構的聯合。 我遇到一個包含另一個結構數組的結構的問題。

[StructLayout(LayoutKind.Explicit)]
public struct FruitBasket
{
    [MarshalAs(UnmanagedType.Struct)]
    [FieldOffset(0)]
    public Apples Apple;

    [FieldOffset(0)]
    public Grapes Grape;

    [FieldOffset(0)]
    public Oranges Orange;
}

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi, Size = 12)]
public struct Apples
{
    public int Color;
    public int Texture;

    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 15)]
    public Types[] Type;

}

如果僅使用Apple結構,則封送處理效果很好。 但是,如果我嘗試做類似的事情;

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi]
public class Buffet
{
    public UInt32 NumMeats;

    public UInt32 NumVeggies;

    public FruitBasket NumFruits;  //public Apples Apple; <-- works fine
}

我收到以下錯誤;

程序集'Test,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'中的FruitBasket',因為它包含偏移量為0的對象字段,該對象字段錯誤地與非對象字段對齊或重疊。

問題是數組是引用類型( MarshalAs不會更改它-僅在執行pinvoke時適用)。 這意味着在結構中存在對其他地方的數組的引用。 而且,在您的情況下,存儲該引用的內存位置與聯合中的其他內容共享,這實際上是行不通的。

因此,您需要的是在struct中包含該數組,如果使用不安全的代碼,則可能這樣 要注意的是:

唯一的限制是數組類型必須為bool,byte,char,short,int,long,sbyte,ushort,uint,ulong,float或double。

因此,有了Types您將無法選擇。 但是,如果可以將其更改為受支持的類型之一,則可以這樣做:

public unsafe struct Apples
{
    public int Color;
    public int Texture;

    public fixed int Type[15];
}

編輯:是的,正如@ IllidanS4所提到的-如果您需要使用除這些類型(結構)之外的任何其他內容,則可以手動地逐個添加這15個字段。 不太整齊...

編輯2:第二個選擇是一起跳過所有聯合-制作三個單獨的結構,並讓Marshal.PtrToStructure使用Marshal.PtrToStructure為您解決。 在這種情況下, MarshalAs將適用於該數組,避免使用fixed 雖然您將必須執行三遍,但這可能是一種更實際的選擇。

MarshalAsFieldOffsetStructLayout不同。 MarshalAs只是一個“常規”參數,向Marshaller指示如何封送字段,它修改了結構的非托管布局。 另一方面,當在C#中使用FieldOffset直接修改結構的托管布局。 MarshalAs對托管環境中的結構布局沒有影響。 因此,它不會使Types固定大小的值數組,因此CLR仍然會抱怨引用被一個值覆蓋(包含在另一個偏移量相同的結構中)。

對於原始類型,您可以使用fixed ,但是恐怕它不適用於Type 我想,您剩下的就是為“數組”的每個元素創建一個具有15個物理字段的結構。 不要忘記,它僅在Types是一個結構(或枚舉)而不是引用時才有效。

盡管如此,僅在P / Invoke中,這通常不是解決常見問題的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM