473,498 Members | 1,832 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

StructLayout and unions

I have a struct that i want to emulate a C++ style union:

[StructLayout(LayoutKind.Explicit)]
public struct Samp
{
[FieldOffset(0)] public byte[] byteBuf;
[FieldOffset(0)] public int[] intBuf;

public Samp(int sz)
{
byteBuf = new byte[sz];
intBuf = new int[sz];
}
}

To be honest, i don't really understand what's going on here. My
understanding is that an 'int' is 32 bits. A byte is 8 bits. The union of a
'int' with a byte array should only require 4 bytes. Therefore, a byte array
of 8 should be able to hold 2 ints. But, if i try the following:

[StructLayout(LayoutKind.Explicit)]
public struct Samp
{
[FieldOffset(0)] public byte[] byteBuf;
[FieldOffset(0)] public int[] intBuf;

public Samp(int sz)
{
byteBuf = new byte[sz];
intBuf = new int[sz/4]; // note smaller size
}
}

and access the byte array beyond byte[3], I get an OutOfRangeException.

Does this mean that I have to allocate 4 bytes for every byte that I
allocate in the byte array to accomodate the ints? That kind of defeats one
of the benefits of unions...
Nov 16 '05 #1
6 6655
Chuck,

Personally I'd forget about the union, and use Buffer.BlockCopy to
copy data between a byte[] and int[]. Using explicit field offsets for
arrays like that doesn't work since the union consists of the array
references, not their data.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 16 '05 #2
There will be no data beyond index 3, arrays in .Net are zero
based...your 4 bytes are 0,1,2,3

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph

Chuck Bowling wrote:
I have a struct that i want to emulate a C++ style union:

[StructLayout(LayoutKind.Explicit)]
public struct Samp
{
[FieldOffset(0)] public byte[] byteBuf;
[FieldOffset(0)] public int[] intBuf;

public Samp(int sz)
{
byteBuf = new byte[sz];
intBuf = new int[sz];
}
}

To be honest, i don't really understand what's going on here. My
understanding is that an 'int' is 32 bits. A byte is 8 bits. The union of a
'int' with a byte array should only require 4 bytes. Therefore, a byte array
of 8 should be able to hold 2 ints. But, if i try the following:

[StructLayout(LayoutKind.Explicit)]
public struct Samp
{
[FieldOffset(0)] public byte[] byteBuf;
[FieldOffset(0)] public int[] intBuf;

public Samp(int sz)
{
byteBuf = new byte[sz];
intBuf = new int[sz/4]; // note smaller size
}
}

and access the byte array beyond byte[3], I get an OutOfRangeException.

Does this mean that I have to allocate 4 bytes for every byte that I
allocate in the byte array to accomodate the ints? That kind of defeats one
of the benefits of unions...

Nov 16 '05 #3
yes Sinjin, i know that...

However, if i allocate and int buffer consisting of 2 ints, i should be able
to access the byte array at byte[4] because the buffer should be 8 bytes
long.

"Sijin Joseph" <si***************@hotmail.com> wrote in message
news:Oc**************@TK2MSFTNGP10.phx.gbl...
There will be no data beyond index 3, arrays in .Net are zero
based...your 4 bytes are 0,1,2,3

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph

Chuck Bowling wrote:
I have a struct that i want to emulate a C++ style union:

[StructLayout(LayoutKind.Explicit)]
public struct Samp
{
[FieldOffset(0)] public byte[] byteBuf;
[FieldOffset(0)] public int[] intBuf;

public Samp(int sz)
{
byteBuf = new byte[sz];
intBuf = new int[sz];
}
}

To be honest, i don't really understand what's going on here. My
understanding is that an 'int' is 32 bits. A byte is 8 bits. The union of a 'int' with a byte array should only require 4 bytes. Therefore, a byte array of 8 should be able to hold 2 ints. But, if i try the following:

[StructLayout(LayoutKind.Explicit)]
public struct Samp
{
[FieldOffset(0)] public byte[] byteBuf;
[FieldOffset(0)] public int[] intBuf;

public Samp(int sz)
{
byteBuf = new byte[sz];
intBuf = new int[sz/4]; // note smaller size
}
}

and access the byte array beyond byte[3], I get an OutOfRangeException.

Does this mean that I have to allocate 4 bytes for every byte that I
allocate in the byte array to accomodate the ints? That kind of defeats one of the benefits of unions...

Nov 16 '05 #4
Thank you for the suggestion Mattias. I'm trying to read a stream into a
structure. Depending on the info in the header of the stream the data will
be either bytes, shorts, or ints. The problem is that the data can also be
packed ints 24 bits long that will need to be expanded to 32 bits. Anyway,
i'll figure it out. I'm sure that if i bang my head on the monitor hard
enough the solution will leak thru... :)

"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:u$**************@TK2MSFTNGP12.phx.gbl...
Chuck,

Personally I'd forget about the union, and use Buffer.BlockCopy to
copy data between a byte[] and int[]. Using explicit field offsets for
arrays like that doesn't work since the union consists of the array
references, not their data.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 16 '05 #5
Check out this article
http://msdn.microsoft.com/library/de...gforarrays.asp

The problem is that since Arrays are reference types at FieldOffset 0 in
ur struct there are just pointers to the actual arrays on the heap.

you need to put the MarshalAs(UnmanagedType.ByValArray) attribute on
your field declaration, but that requires the size to be fixed. I guess
you will have to use a pointer type then. Check out the custom
marshalling articles on MSDN related to the link above, they should be
of help.

Let me know if you get stuck.

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph

Chuck Bowling wrote:
yes Sinjin, i know that...

However, if i allocate and int buffer consisting of 2 ints, i should be able
to access the byte array at byte[4] because the buffer should be 8 bytes
long.

"Sijin Joseph" <si***************@hotmail.com> wrote in message
news:Oc**************@TK2MSFTNGP10.phx.gbl...
There will be no data beyond index 3, arrays in .Net are zero
based...your 4 bytes are 0,1,2,3

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph

Chuck Bowling wrote:
I have a struct that i want to emulate a C++ style union:

[StructLayout(LayoutKind.Explicit)]
public struct Samp
{
[FieldOffset(0)] public byte[] byteBuf;
[FieldOffset(0)] public int[] intBuf;

public Samp(int sz)
{
byteBuf = new byte[sz];
intBuf = new int[sz];
}
}

To be honest, i don't really understand what's going on here. My
understanding is that an 'int' is 32 bits. A byte is 8 bits. The union
of a
'int' with a byte array should only require 4 bytes. Therefore, a byte
array
of 8 should be able to hold 2 ints. But, if i try the following:

[StructLayout(LayoutKind.Explicit)]
public struct Samp
{
[FieldOffset(0)] public byte[] byteBuf;
[FieldOffset(0)] public int[] intBuf;

public Samp(int sz)
{
byteBuf = new byte[sz];
intBuf = new int[sz/4]; // note smaller size
}
}

and access the byte array beyond byte[3], I get an OutOfRangeException.

Does this mean that I have to allocate 4 bytes for every byte that I
allocate in the byte array to accomodate the ints? That kind of defeats
one
of the benefits of unions...


Nov 16 '05 #6
Thanks for your help Sijin. I'm looking at a different approach right now. I
needed to tweak my Stream class anyhow... ;)

"Sijin Joseph" <si***************@hotmail.com> wrote in message
news:ut**************@tk2msftngp13.phx.gbl...
Check out this article
http://msdn.microsoft.com/library/de...gforarrays.asp
The problem is that since Arrays are reference types at FieldOffset 0 in
ur struct there are just pointers to the actual arrays on the heap.

you need to put the MarshalAs(UnmanagedType.ByValArray) attribute on
your field declaration, but that requires the size to be fixed. I guess
you will have to use a pointer type then. Check out the custom
marshalling articles on MSDN related to the link above, they should be
of help.

Let me know if you get stuck.

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph

Chuck Bowling wrote:
yes Sinjin, i know that...

However, if i allocate and int buffer consisting of 2 ints, i should be able to access the byte array at byte[4] because the buffer should be 8 bytes
long.

"Sijin Joseph" <si***************@hotmail.com> wrote in message
news:Oc**************@TK2MSFTNGP10.phx.gbl...
There will be no data beyond index 3, arrays in .Net are zero
based...your 4 bytes are 0,1,2,3

Sijin Joseph
http://www.indiangeek.net
http://weblogs.asp.net/sjoseph

Chuck Bowling wrote:

I have a struct that i want to emulate a C++ style union:

[StructLayout(LayoutKind.Explicit)]
public struct Samp
{
[FieldOffset(0)] public byte[] byteBuf;
[FieldOffset(0)] public int[] intBuf;

public Samp(int sz)
{
byteBuf = new byte[sz];
intBuf = new int[sz];
}
}

To be honest, i don't really understand what's going on here. My
understanding is that an 'int' is 32 bits. A byte is 8 bits. The union


of a
'int' with a byte array should only require 4 bytes. Therefore, a byte


array
of 8 should be able to hold 2 ints. But, if i try the following:

[StructLayout(LayoutKind.Explicit)]
public struct Samp
{
[FieldOffset(0)] public byte[] byteBuf;
[FieldOffset(0)] public int[] intBuf;

public Samp(int sz)
{
byteBuf = new byte[sz];
intBuf = new int[sz/4]; // note smaller size
}
}

and access the byte array beyond byte[3], I get an OutOfRangeException.

Does this mean that I have to allocate 4 bytes for every byte that I
allocate in the byte array to accomodate the ints? That kind of defeats


one
of the benefits of unions...


Nov 16 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
5251
by: David | last post by:
Some developers in my group are using UNIONS to define their data types in a C++ program for an embedded system. Are there any pro and cons in doing this when you can define a CLASS to do the same...
6
13360
by: Neil Zanella | last post by:
Hello, I would like to know whether the following C fragment is legal in standard C and behaves as intended under conforming implementations... union foo { char c; double d; };
16
3921
by: Tim Cambrant | last post by:
Hi. I was reading up a bit on the features of C I seldom use, and I came across unions. I understand the concept, and that all the contained variables etc. share the same memory. Thus, when a new...
23
2786
by: rohit | last post by:
Hi, In my couple of years of experience, I have never found a single instance where I needed to use unions and bitfields(though I have used structures).I was just imagining where would these find...
2
12304
by: Al Bahr | last post by:
H I am try to convert C# to vb.net I don’t know what would be an equivalent statements in VB.net any help will be appreciated. bmiColors ' RGBQUAD structs... Blue-Green-Red-Reserved, repeat.....
4
1747
by: uralmutlu | last post by:
Hi, I was wandering if I can have classes in unions? I basically have source code in a format very similar to: union example { ClassA variable1; ClassB variable2; };
67
3292
by: bluejack | last post by:
A recent post asking for help with unions reminded me of this component of the C language that I have only used a couple of times, and those almost entirely out of personal whim -- Unions for the...
26
1889
by: Old Wolf | last post by:
Ok, we've had two long and haphazard threads about unions recently, and I still don't feel any closer to certainty about what is permitted and what isn't. The other thread topics were "Real Life...
11
1992
by: pereges | last post by:
Hello, can some one please guide me a little into using unions. I read about unions in K & R but I am finding it difficult to apply to my problem at hand. I want to save up some space by using...
0
7121
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7162
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7197
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6881
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5456
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
3088
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3078
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
650
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
287
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.