Results 1 to 8 of 8

Thread: [RESOLVED] Structure as union in VB.NET. Is this declaration valid?

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    May 2005
    Posts
    530

    Resolved [RESOLVED] Structure as union in VB.NET. Is this declaration valid?

    I want to use a structure as a union in VB.NET 2010. Is the following structure declaration valid?

    Code:
        <StructLayout(LayoutKind.Explicit)> Public Structure Int32ByteUnion
            <FieldOffset(0)> Dim ByteVal() As Byte
            <FieldOffset(0)> Dim i32Val As Int32
        End Structure
    It doesn't give errors, unless I attempt to dimension the size of ByteVal. In this case, I want ByteVal to be 4 bytes so each byte of the Int32 has a corresponding ByteVal element. Given that it shows an error if I dimension the array size, and doesn't if I don't, how does it know what size to make the array? Or, does this even work like I'm expecting?
    Thanks.

  2. #2
    I'm about to be a PowerPoster! kleinma's Avatar
    Join Date
    Nov 2001
    Location
    NJ - USA (Near NYC)
    Posts
    23,373

    Re: Structure as union in VB.NET. Is this declaration valid?

    I honestly don't know a whole lot about unions, but I know that you can't offset fields over each other like that when one is an object (reference) type and one is a value type. In32 is a value type, and while Byte also is, arrays in .NET are objects, so this would probably fail if you were to run it.

  3. #3
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,585

    Re: Structure as union in VB.NET. Is this declaration valid?

    The declaration is not valid.
    I'm not sure if there is a way to make it valid.
    Are you going to have to interface with something expecting that structure?
    If not, you could probably just create the members without being specific about the layout, and then provide set methods that can copy members between representations when they are set.

    For instance, here is a structure with the two members you have, and when you set the i32Val, the bytes are copied into the byte array.
    If you need to go both directions, then the byte array should also be made a property with access methods, instead of making it Public.
    Code:
    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
      Public Structure Int32ByteUnion
        Public ByteVal() As Byte  'Our byte array representation of _i32Val
    
        Private _i32Val As Int32  '
        Property i32Val As Int32
          Get
            Return _i32Val
          End Get
    
          Set(ByVal value As Int32)
            _i32Val = value                            'When we set _i32Val
            ByteVal = BitConverter.GetBytes(_i32Val)   'Also set the byte array
          End Set
        End Property
      End Structure
    
      Dim s As Int32ByteUnion
    
      Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        s.i32Val = 65535             'Set i32Val to 0000ffff
        For i As Integer = 0 To 3
          Debug.Print(s.ByteVal(i))  'verify we get 255 255 0 0 from the byte array
        Next
      End Sub
    End Class

  4. #4

    Thread Starter
    Fanatic Member
    Join Date
    May 2005
    Posts
    530

    Re: Structure as union in VB.NET. Is this declaration valid?

    Thanks for the explanation Kleinma. That is a detail I knew a while back but have since forgotten. One of the hazards of occasional programming.
    Passel, looks like your solution will work fine. I'll give that a try.
    Thanks.

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,837

    Re: [RESOLVED] Structure as union in VB.NET. Is this declaration valid?

    What's the point of the array of bytes that relates to an integer? After all, an array would just be a consecutive sequence of memory blocks of the size based on the array type. In this case, since the array is an array of bytes, that means that an array of four bytes would just mean four consecutive bytes of memory...which is an integer. The only fundamental difference between an integer and an array of four bytes is typically that the address has a means of obtaining the bytes by index (in .NET, since an array is a reference type, there is more differences than just that, but the underlying block of memory isn't different). You could add a few methods to the structure that would get the bytes from the integer by index, and the integer would BE your array.
    My usual boring signature: Nothing

  6. #6
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,585

    Re: [RESOLVED] Structure as union in VB.NET. Is this declaration valid?

    It is true that you could have methods to extract the bytes from the integer, although the syntax would be a bit different compared to accessing the array.
    Of course the real reason behind the original desire is that in C and C++ you often have unions defined to handle fields of a dynamic type in a structure.
    For instance, one of the short messages in the CIGI (Common Image Generator Interface) standard is the Short Component Control packet.
    It is a 16-byte message, the last 8 bytes being treated as two generic 32-bit words containing Component Data (Component Data 1, Component Data 2).
    Although the ICD says the Component Data words will be treated as a 32-bit value so are subject to byte swapping when communicating between machines with different endianess, the data in those words do not have to be 32-bit values. It is up to the IG vendor to specify what type the Component Data is, for any given Component ID.
    For instance, Component Data 1, could be a 32-bit signed integer, but it could be a 32-bit Single. It could also be two shorts, or four bytes.
    That fact is since byte-swapping will always occur is actually a pain, since a four byte byte array should not be swapped when going between machines of different endianess, but that is another matter not really germane to this thread.
    Since the data type is flexible, the common approach in C and C++ would be to create a Union, so that you can look at the component word by any of the types it might hold, i.e. a union of four bytes, two shorts, a four byte integer, or a single. That way you just read and write whichever data type you need.

    That is why I asked if the structure had to match a specific layout to meet the needs of a defined interface.
    The code I gave definitely would not do that.
    The reason I copied the Integer to a four byte array, is that in accessing the bytes in the array, I assume there would be less overhead in the access, versus providing methods to extract the bytes from an integer each access, so the code is trading memory for access speed, the conversion to bytes only having to be done once when assigned, rather than every time accessed.

    On the other hand, if I did have to match a defined interface at the bit level, then I would do along the lines of what Shaggy Hiker says, but I've always done it the other way around. Rather than pack various data types into a structure and try to force them to layout correctly, I would just create an array of bytes, e.g. for the Short Component Control packet, I would have an array of 16 bytes, which I could easily transfer as needed, over a serial link or Ethernet, or between methods, etc. since serial links and Ethernet have always been setup to except arrays of bytes as data for transmittal.
    I would provide methods to store or retrieve the various types, i.e Integer, bytes, Shorts, singles, etc. to and from the byte array at the correct offset.
    Doing that, I'm much more confident that the layout matches what is required for inter-communications, is fairly straight forward and my feeling is that doing the conversion from byte array to and from various types on the reading and writing is relatively efficient as you have .Net methods already defined to do those conversions, so should be essentially inline memory copy routines.
    Last edited by passel; Apr 21st, 2014 at 01:46 PM.

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    May 2005
    Posts
    530

    Re: [RESOLVED] Structure as union in VB.NET. Is this declaration valid?

    I just needed to build a large array out of smaller arrays to save a bunch of data (ints, singles and strings) to a binary file. I also needed to control the endianness of the bytes because of the way another program reads the file. Works now. Thanks.

  8. #8
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,798

    Re: [RESOLVED] Structure as union in VB.NET. Is this declaration valid?

    Quote Originally Posted by rickford66 View Post
    I want to use a structure as a union in VB.NET 2010. Is the following structure declaration valid?

    Code:
        <StructLayout(LayoutKind.Explicit)> Public Structure Int32ByteUnion
            <FieldOffset(0)> Dim ByteVal() As Byte
            <FieldOffset(0)> Dim i32Val As Int32
        End Structure
    Generally this is the correct thinking. If the fields were simple types this would be the way to go about it but in this case, that dynamic array would make this an atypical situation.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width