-
Apr 17th, 2014, 03:32 PM
#1
Thread Starter
Fanatic Member
[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.
-
Apr 17th, 2014, 04:24 PM
#2
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.
-
Apr 17th, 2014, 04:51 PM
#3
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
-
Apr 21st, 2014, 09:55 AM
#4
Thread Starter
Fanatic Member
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.
-
Apr 21st, 2014, 11:03 AM
#5
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
 
-
Apr 21st, 2014, 01:40 PM
#6
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.
-
Apr 22nd, 2014, 02:15 PM
#7
Thread Starter
Fanatic Member
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.
-
Apr 23rd, 2014, 12:16 AM
#8
Re: [RESOLVED] Structure as union in VB.NET. Is this declaration valid?
 Originally Posted by rickford66
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|