How to write typedef structs and unions in C#

I have this code from a C++ project I want to migrate to C#. How would I write this in C#

typedef struct _hdr_struct
{ char fileType[ 4];
  union
 
{ char fileVersion[ 4];
   
struct
   
{ char v;
      char major;
      char dot;
      char minor;
    } version;
  };
} HDRSTRUCT, *LPHDRSTRUCT;

// Then later
char buffer[ 1024];
// code to fill the buffer
LPHDRSTRUCT lpHS = (LPHDRSTRUCT) &buffer;

char major = lpHS->version.major;

 



Answer this question

How to write typedef structs and unions in C#

  • Liu Qiang

    Oh I see. We're stepping backwards to 1985 techniques now. Just how that is supposed to be easier I'll never figure out. But thanks for the example man I appreciate it.


  • Sam Tyson 92



    class HD
    {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
    public string fileType;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
    public string fileVersion;

    public char Major
    {
    get
    {
    return fileVersion[ 1 ];
    }
    }
    public byte Minor
    {
    get
    {
    return fileVersion[ 3 ];
    }
    }
    }




  • arogan

    I appreciate short and to the point answers... but any chance for a little elaboration on that Maybe clue me in on the new method to achieve something like this
  • Bravo2007

    Axe22 wrote:

    Oh I see. We're stepping backwards to 1985 techniques now. Just how that is supposed to be easier I'll never figure out. But thanks for the example man I appreciate it.

    How is that stepping backwards


  • thomas f

    You can't.
  • vijil

    Hi,

    There, we have discussed about how to simulate an union in C#: https://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1052142&SiteID=1

    Thank you



  • Danny_FADBA

     Axe22 wrote:
     Paul Louth wrote:
     Axe22 wrote:

    Oh I see. We're stepping backwards to 1985 techniques now. Just how that is supposed to be easier I'll never figure out. But thanks for the example man I appreciate it.

     

    How is that stepping backwards  

    Because the native structure of the block is totally obscured by all those property functions, character-by-character indexing conversions, and bitwise operators -- like it was in 1985, tiny little functions everywhere to grab each little piece. It takes three times as many lines to write it.

     

    It actually encapsulates the data, which is considered the foundation of object oriented design.  The idea is to keep the implementation as close to the data as possible.  By exposing byte arrays with direct access you spread the implementation all over your code-base and reduce extensiblity.

    It may take 3 times as many lines to write it, but it takes far less time to debug that class than debug every method that ever uses it.  It is far less prone to error than your method. 

    That is the future :o)


  • Rhubarb

    Unions are a bit of a fudge really, and aren't in the spirit of OOP, so that I assume is why they were dropped from C#.

    C# works with class's and struct's.  They're the only fundamental types in the language.  A class is an object-type, a struct is a value type. 

    C# is a strongly typed language, which means you can't pretend one type is another by casting (unless implicit or explicit conversion operators exist for those types, but that's still not the same as C++ casting), and you can't fool the language into believing an int array is a char array for example, as the type is attached strongly to the instance.

    From your example I can't tell whether buffer holds 128 _hdr_struct, or 1 _hdr_struct and the rest of it is the file contents.  This is one of the major issues with C++ in that the type system is so fundamentally broken.  It leads to structure corruption issues, buffer overflows etc.  C# doesn't allow this.  If I was to try and implement your code as C#, then I might do something like this (assuming you have 1 _hdr_struct and the rest is file-content);

    public class MyFile
    {
        byte[] buffer;

        public MyFile(string fileName)
        {
            buffer = File.ReadAllBytes(fileName);
        }

        public int FileType
        {
            get
            {
                return (int)buffer[ 0 ] | ((int)buffer[ 1 ] << 8) | ((int)buffer[ 2 ] << 16) | ((int)buffer[ 3 ] << 24);
            }
        }

        public int FileVersion
        {
             get
            {
                return (int)buffer[ 4 ] | ((int)buffer[ 5 ] << 8) | ((int)buffer[ 6 ] << 16) | ((int)buffer[ 7 ] << 24);
            }
        }

        public byte V
        {
            get
            {   
                return buffer[ 4 ];
            }
        }

        public byte Major
        {
            get
            {
                return buffer[ 5 ];
            }
        }

        public byte Dot
        {
            get
            {
                return buffer[ 6 ];
            }
        }

        public byte Minor
        {
            get
            {
                return buffer[ 7 ];
            }
         }

         public byte this[int index]
         {
             get
             {
                 return buffer[index + 8];
             }
         }
     }


  • Redfox72

  • akuhad

    Paul Louth wrote:
    Axe22 wrote:

    Oh I see. We're stepping backwards to 1985 techniques now. Just how that is supposed to be easier I'll never figure out. But thanks for the example man I appreciate it.

    How is that stepping backwards

    Because the native structure of the block is totally obscured by all those property functions, character-by-character indexing conversions, and bitwise operators -- like it was in 1985, tiny little functions everywhere to grab each little piece. It takes three times as many lines to write it.


  • How to write typedef structs and unions in C#