简体   繁体   English

C#中的C风格联盟

[英]C-Style Unions in C#

I apologize for the naming of these fields, but I'm have to block out things like field names based on an NDA. 我为这些字段的命名道歉,但我必须阻止基于NDA的字段名称之类的内容。

So basically I am in C# and I am using Interop to communicate with an external library, which requires specific structures to be passed by reference, one of which uses a union. 所以基本上我在C#中,我使用Interop与外部库进行通信,这需要通过引用传递特定结构,其中一个使用union。 This is the struct that seems to be giving me a headache, because I have found a few references online on how to union two data types but not two structs together. 这个结构似乎让我头疼,因为我在网上找到了一些关于如何将两种数据类型结合在一起而不是两种结构的引用。 Here are the basics of the two struct 以下是两个结构的基础知识

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;
}

What would the resulting structs look like in c#? 结果结构在c#中会是什么样的? I have had a few ideas, some of which seem to work but result in a blue screen with a message of reference_by_pointer after a while, and I was thinking that maybe some thing about my struct definition is wrong, and somehow the data is not fitting in the struct correctly. 我有一些想法,其中一些似乎有效,但在一段时间后会产生一个带有reference_by_pointer消息的蓝屏,我想我的结构定义可能有些错误,而且数据不合适在结构中正确。 Here is what I currently have: 这是我目前拥有的:

    [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;
    }

Am I doing this all wrong? 我做错了吗?

EDIT: In response to a request for more info, here is an example usage, but not that I cannot provide the population of the fields because that is hidden in the API. 编辑:响应更多信息的请求,这是一个示例用法,但不是我不能提供字段的填充,因为它隐藏在API中。

Also, it is possible it is a problem with the API, but that is more unlikely than me screwing up the Interop to it. 此外,它可能是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;
        }
    }

I apologize for not being able to provide absolute calls or true context, but I must honor NDA's even if it means reducing the quality of answers. 我为无法提供绝对电话或真实背景而道歉,但我必须尊重NDA,即使这意味着降低答案的质量。

EDIT 2: Is it at all possible that the two different sized datatypes being unioned together is having any affect on this situation? 编辑2:两种不同大小的数据类型联合在一起对这种情况有任何影响吗? I know that datatype1 has size of 7 bytes and datatype2 has a size of 8 bytes. 我知道datatype1的大小为7个字节,datatype2的大小为8个字节。 Could this cause some sort of memory issue? 这会导致某种内存问题吗?

There is no problem with your C# union. 你的C#union没有问题。 However, field15 is wrong. 但是, field15是错误的。 It's char in the C code and byte[] in the C# code. 它是C代码中的char和C#代码中的byte[] You need to declare it as byte in the C# code. 您需要在C#代码中将其声明为byte

For what it's worth, you are safe to omit LayoutKind.Sequential since that is the default for a struct. 对于它的价值,您可以安全地省略LayoutKind.Sequential因为这是结构的默认值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM