簡體   English   中英

C#中的C風格聯盟

[英]C-Style Unions in C#

我為這些字段的命名道歉,但我必須阻止基於NDA的字段名稱之類的內容。

所以基本上我在C#中,我使用Interop與外部庫進行通信,這需要通過引用傳遞特定結構,其中一個使用union。 這個結構似乎讓我頭疼,因為我在網上找到了一些關於如何將兩種數據類型結合在一起而不是兩種結構的引用。 以下是兩個結構的基礎知識

struct datatype1
{ 
    char field1; 
    char field2; 
    char field3;
    char field4;
    char field5; 
    char field6; 
    char field7; 
};

struct datatype2
{
    public uint field8;
    public uint field9;
}

struct datatype3
{
    unsigned int field10;
    union
    {
        datatype1 field11;
        datatype2 field12;
    } field13;
    uint field14;
    unsigned char field15;
    uint field16;
}

結果結構在c#中會是什么樣的? 我有一些想法,其中一些似乎有效,但在一段時間后會產生一個帶有reference_by_pointer消息的藍屏,我想我的結構定義可能有些錯誤,而且數據不合適在結構中正確。 這是我目前擁有的:

    [StructLayout( LayoutKind.Sequential )]
    public struct datatype1
    {
        public byte field1;
        public byte field2;
        public byte field3;
        public byte field4;
        public byte field5;
        public byte field6;
        public byte field7;
    }

    [StructLayout( LayoutKind.Sequential )]
    public struct datatype2
    {
        public uint field8; // Digital i/p event
        public uint field9;
    }

    public struct datatype3
    {
        public uint field10;

        [StructLayout( LayoutKind.Explicit )]
        public struct AnonymousStruct
        {
            [FieldOffset( 0 )]
            public datatype1 field11;

            [FieldOffset( 0 )]
            public datatype2 field12;
        }

        public AnonymousStruct field13;

        public uint field14;

        public byte[] field15;

        public uint field16;
    }

我做錯了嗎?

編輯:響應更多信息的請求,這是一個示例用法,但不是我不能提供字段的填充,因為它隱藏在API中。

此外,它可能是API的一個問題,但這比我將Interop搞砸了。

    ...inside thread....
    datatype3 dt = new datatype3();
    while( true )
    {
        api.get_next_value( ref dt );
        PrintData( dt );
        Thread.Sleep( 55 );
    }


    /// <summary>
    /// Prints the data from the event.  Used for debugging purposes.
    /// </summary>
    /// <param name="evp"></param>
    private void PrintData( datatype3 evp )
    {
        if( evp.field10 == 2 )
        {
            Console.WriteLine( "datatype2" );
            Console.WriteLine( "\tfield8val: " + evp.field13.field12.field8);
            Console.WriteLine( "\tfield9val: " + evp.field13.field12.field9 );
        }
        else if( evp.de_type == 1 )
        {
            Console.WriteLine( "datatype1" );
            Console.WriteLine( "\tfield1val:  " + evp.field13.field12.field1 );
            Console.WriteLine( "\tfield2val:  " + evp.field13.field12.field2 );
            Console.WriteLine( "\tfield3val:  " + evp.field13.field12.field3 );
            Console.WriteLine( "\tfield4val:  " + evp.field13.field12.field4 );
            Console.WriteLine( "\tfield5val:  " + evp.field13.field12.field5 );
            Console.WriteLine( "\tfield6val:  " + evp.field13.field12.field6 );
            Console.WriteLine( "\tfield7val:  " + evp.field13.field12.field7 );
        }
        else
        {
            return;
        }
    }

我為無法提供絕對電話或真實背景而道歉,但我必須尊重NDA,即使這意味着降低答案的質量。

編輯2:兩種不同大小的數據類型聯合在一起對這種情況有任何影響嗎? 我知道datatype1的大小為7個字節,datatype2的大小為8個字節。 這會導致某種內存問題嗎?

你的C#union沒有問題。 但是, field15是錯誤的。 它是C代碼中的char和C#代碼中的byte[] 您需要在C#代碼中將其聲明為byte

對於它的價值,您可以安全地省略LayoutKind.Sequential因為這是結構的默認值。

暫無
暫無

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

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