locked
equivlaent use of union in C

    Question

  •       I'm trying to use the equivalent of a union here.  I'm getting the following error message - MissinngMethodException was unhandled.   The code compiled OK but I get the exception.  How should this be coded to work?

     

            [StructLayout(LayoutKind.Explicit)]
            public struct DataType
            {
                [FieldOffset(0)]
                public string dstring;
                [FieldOffset(0)]
                public int dint;
                [FieldOffset(0)]
                public float dfloat;
                [FieldOffset(0)]
                public double ddouble;
                [FieldOffset(0)]
                public char dchar;
                [FieldOffset(0)]
                public byte dbyte;
            }

            public struct XMLData
            {
                public string Tag;
                public DataType Item;
                public XMLData(string tag, DataType item)
                {
                    this.Tag = tag;
                    this.Item = item;
                }
            }

              public LinkedList<XMLData> LL = new LinkedList<XMLData>();

    Friday, September 22, 2006 7:40 PM

All replies

  • The code you posted work fine for me.  The error is apparently elsewhere in the code. 

    Try post a short-but-complete program (http://yoda.arachsys.com/csharp/complete.html) which shows the error.

    Friday, September 22, 2006 8:30 PM
  • Error is..... TypeLoad Exception unhandled

     

    Could not load type 'DataType' from assembly 'WinTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.

     

    Code Example:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;

    namespace WinTest
    {
        public partial class Form1 : Form
        {
       
            [StructLayout(LayoutKind.Explicit)]
            public struct DataType
            {
                [FieldOffset(0)]
                public string Dstring;
                [FieldOffset(0)]
                public int Dint;
                [FieldOffset(0)]
                public float Dfloat;
                [FieldOffset(0)]
                public double Ddouble;
                [FieldOffset(0)]
                public char Dchar;
                public DataType(string dstring, int dint, float dfloat, double ddouble, char dchar)
                {
                    this.Dstring = dstring;
                    this.Dint = dint;
                    this.Dfloat = dfloat;
                    this.Ddouble = ddouble;
                    this.Dchar = dchar;
                }
            }
            public DataType DType = new DataType();
            public struct XMLData
            {
                public string Tag;
                public DataType Item;
                public XMLData(string tag, DataType item)
                {
                    this.Tag = tag;
                    this.Item = item;
                }
            }

            XMLData xmldata;
            LinkedList<XMLData> LL;
     
            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                xmldata = new XMLData("", DType);
                LL = new LinkedList<XMLData>();
                LL.AddLast(xmldata);
            }
        }
    }

    Friday, September 22, 2006 9:44 PM
  • StructLayout(Layoutkind.Explicit] won't work for strings.  I replaced explicit and has a precise offset value with sequential layout.   Explicit layouts are not permitted with reference types like the String in the example code.

          

           [StructLayout(LayoutKind.Sequential)]
            public struct DataType
            {
               [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public String Dstring;
               [MarshalAs(UnmanagedType.I4)] public int Dint;
               [MarshalAs(UnmanagedType.R4)] public float Dfloat;
               [MarshalAs(UnmanagedType.R8)] public double Ddouble;
               [MarshalAs(UnmanagedType.U1)] public byte Dbyte;
               public DataType(String dstring, int dint, float dfloat, double ddouble, byte dbyte)
                {
                    this.Dstring = dstring;
                    this.Dint = dint;
                    this.Dfloat = dfloat;
                    this.Ddouble = ddouble;
                    this.Dbyte = dbyte;
                }
            }

            public struct XMLData
            {
                public string Tag;
                public DataType Item;
                public XMLData(string tag, DataType item)
                {
                    this.Tag = tag;
                    this.Item = item;
                }
            }

            public XMLData xmldata = new XMLData();

            public LinkedList<XMLData> LL = new LinkedList<XMLData>();
            public LinkedListNode<XMLData> LLN;

    Monday, September 25, 2006 6:38 PM
  •     public DataType(string dstring, int dint, float dfloat, double ddouble, char dchar)
                {
                    this.Dstring = dstring;
                    this.Dint = dint;
                    this.Dfloat = dfloat;
                    this.Ddouble = ddouble;
                    this.Dchar = dchar;
                }

    That's not going to work.  dfloat will overwrite what's in Dint.  ddouble will overwrite what's in Dfloat. Then finally Dchar will overwrite what's in Ddouble.  Leaving Dchar the only correct value.

     


    Tuesday, September 26, 2006 7:43 PM