By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,208 Members | 1,592 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,208 IT Pros & Developers. It's quick & easy.

What Can I Expect From This Union?

P: n/a
Within the following structure, TopStruct, I'd like to create 3 other
structures, 2 of which make up a union. The first structure will always
contain some data that I need and should never be overwritten, i.e. should
not be part of the union. The remaining 2, UnionData1 and UnionData2, make
up the union and are populated as needed.

I want to be certain that this code will work as planned. Specifically, if
the field offsets of the first union members are set to '0', will they
overwrite the data in the first structure, AlwaysContainsData? Or should
they be changed to the values indicated in the inline comments?

Essentially, I don't know if the FieldOffset attribute applies to the struct
in which it's called, e.g. UnionData1, or to the top-level struct,
TopStruct:
public struct TopStruct
{
[StructLayout( LayoutKind.Sequential )]
public struct AlwaysContainsData // Contains 262 bytes of data.
{
public short dataType;
public short rmsVolt;
public short rmsCurr;

[MarshalAs( UnmanagedType.ByValArray, SizeConst = 128 )]
public short[] waveform;
}

// Begin the structs for the union.
[ StructLayout( LayoutKind.Explicit ) ]
public struct UnionData1
{
[ MarshalAs( UnmanagedType.ByValArray, SizeConst = 128 ) ]
[ FieldOffset( 0 ) ] // or should it be "FieldOffset( 262 )"
?
public short[] waveform2;
}

[ StructLayout( LayoutKind.Explicit ) ]
public struct UnionData2
{
[ MarshalAs( UnmanagedType.ByValArray, SizeConst = 128) ]
[ FieldOffset( 0 ) ] // or should it be "FieldOffset( 262 )"
?
public short[] waveform2;

[ MarshalAs( UnmanagedType.ByValArray, SizeConst = 128) ]
[ FieldOffset( 128 ) ] // or should it be "FieldOffset( 390 )"
?
public short[] waveform3;

}

} // End of TopStruct
Nov 15 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a

Hi Mike,

Because the FieldOffsetAttribute is applied to the UnionData class, I think
your FieldOffset
should be number relative to the UnionData class.
The member of the UnionData class will alloc memory after the first
structure AlwaysContainsData.

I think you can determine this by creating a unmanaged dlll consuming the
union.

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: "Mike" <mi**@bogus.net>
| Subject: What Can I Expect From This Union?
| Date: Tue, 2 Sep 2003 15:15:17 -0400
| Lines: 57
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| Message-ID: <uj**************@TK2MSFTNGP11.phx.gbl>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: dialup-171.75.39.7.dial1.washington1.level3.net
171.75.39.7
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTN GP11.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:181638
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Within the following structure, TopStruct, I'd like to create 3 other
| structures, 2 of which make up a union. The first structure will always
| contain some data that I need and should never be overwritten, i.e. should
| not be part of the union. The remaining 2, UnionData1 and UnionData2,
make
| up the union and are populated as needed.
|
| I want to be certain that this code will work as planned. Specifically,
if
| the field offsets of the first union members are set to '0', will they
| overwrite the data in the first structure, AlwaysContainsData? Or should
| they be changed to the values indicated in the inline comments?
|
| Essentially, I don't know if the FieldOffset attribute applies to the
struct
| in which it's called, e.g. UnionData1, or to the top-level struct,
| TopStruct:
|
|
| public struct TopStruct
| {
| [StructLayout( LayoutKind.Sequential )]
| public struct AlwaysContainsData // Contains 262 bytes of data.
| {
| public short dataType;
| public short rmsVolt;
| public short rmsCurr;
|
| [MarshalAs( UnmanagedType.ByValArray, SizeConst = 128 )]
| public short[] waveform;
| }
|
| // Begin the structs for the union.
| [ StructLayout( LayoutKind.Explicit ) ]
| public struct UnionData1
| {
| [ MarshalAs( UnmanagedType.ByValArray, SizeConst = 128 ) ]
| [ FieldOffset( 0 ) ] // or should it be "FieldOffset( 262
)"
| ?
| public short[] waveform2;
| }
|
| [ StructLayout( LayoutKind.Explicit ) ]
| public struct UnionData2
| {
| [ MarshalAs( UnmanagedType.ByValArray, SizeConst = 128) ]
| [ FieldOffset( 0 ) ] // or should it be "FieldOffset( 262
)"
| ?
| public short[] waveform2;
|
| [ MarshalAs( UnmanagedType.ByValArray, SizeConst = 128) ]
| [ FieldOffset( 128 ) ] // or should it be "FieldOffset( 390
)"
| ?
| public short[] waveform3;
|
| }
|
| } // End of TopStruct
|
|
|

Nov 15 '05 #2

P: n/a
Mike,
Essentially, I don't know if the FieldOffset attribute applies to the struct
in which it's called, e.g. UnionData1, or to the top-level struct,
TopStruct:


The offset is relative to the beginning of the "union" struct itself,
not any containing type.

Note that declaring a type nested inside another type does not
automatically give you a member of that nested type in the containing
type. Specifically, the TopStruct as it's written right now doesn't
have any members.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Nov 15 '05 #3

P: n/a
Thanks for your reply, Mattias.

If the offset is relative to the beginning of the union struct rather than
the containing struct, then the idea of UnionData1 and UnionData2 occupying
the same memory location is incorrect, isn't it?

To clarify matters, I wanted to have a data structure, TopStruct, that
contained some data that will be always populated (AlwaysContainsData
struct) by the data stream, and other data that would populate one of the
union structs or the other (UnionData1 or UnionData2), but not both. Hence,
I don't need to allocate memory for more than one union struct at a time,
though I need all the members within it.

Can I accomplish this?
-Mike
"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:e$**************@TK2MSFTNGP12.phx.gbl...
Mike,
Essentially, I don't know if the FieldOffset attribute applies to the structin which it's called, e.g. UnionData1, or to the top-level struct,
TopStruct:


The offset is relative to the beginning of the "union" struct itself,
not any containing type.

Note that declaring a type nested inside another type does not
automatically give you a member of that nested type in the containing
type. Specifically, the TopStruct as it's written right now doesn't
have any members.

Mattias

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

Nov 15 '05 #4

P: n/a
If the offset is relative to the beginning of the union struct rather than
the containing struct, then the idea of UnionData1 and UnionData2 occupying
the same memory location is incorrect, isn't it?
No, the idea is correct. But it's not always possible to realize. The
fact that you can't overlay object types with value types restricts
what you can do with explicit layout types.

Hence,
I don't need to allocate memory for more than one union struct at a time,


The effective size of a struct with explicit layout (union) is the
same regardless of which part of the union you use, so this will not
necessarily reduce memory allocation.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Nov 15 '05 #5

P: n/a
100,

You've given me food for thought. Thanks for your help.
-Mike

"100" <10*@100.com> wrote in message
news:O7**************@tk2msftngp13.phx.gbl...
Hi Mike
Is it posible to do something like the following. I haven't tried, though.

[ StructLayout( LayoutKind.Explicit ) ]
public struct TopStruct
{
[StructLayout( LayoutKind.Sequential )]
public struct AlwaysContainsData // Contains 262 bytes of data. {
....
}
[ StructLayout( LayoutKind.Explicit ) ]
public struct UnionData1
{
.....
}

[ StructLayout( LayoutKind.Explicit ) ]
public struct UnionData2
{
.....
}

[ FieldOffset( 0 ) ]
public AlwaysContainsData alwaysContainsData ;
[ FieldOffset( 262) ]
public UnionData1 unionData1
[ FieldOffset( 262) ]
public UnionData2 UnionData2
}

So if it works. changing
a field from unionData1 should change unionData2.

TopStruct topStruct = new TopStruct();
topStruct.unionData1.SomeField = ......

In your original example you made a mistake. Decalring a struct nested in
another struct/class doesn't make its members part of the outer struct/class members. It just changes the structure name scope.
So the data fields of AlwaysContainsData, UnionData1 and UnionData2 are not part of the TopStruct members and setting their members' FieldOffset
attributes cannot be releated to the TopStruct.
This is unlike the C++ anonimous structs and unions. To make them part of
the TopStruct you have to declare member variables of those struct types.

You might be able to do the following as well:

[ StructLayout( LayoutKind.Explicit ) ]
public struct TopStruct
{
[FieldOffset( 0 )]
int FirstAlwaysData;
[FieldOffset( 4 )]
int SecAlwaysData;
[FieldOffset( 8 )] //this and the next field occupy the same
memory
int FirstUnion1Data;
[FieldOffset( 8 )]
int FirstUnion2Data;
}

I haven't tested these ideas, though.

HTH
B\rgds
100

"Mike" <mi**@bogus.net> wrote in message
news:OT**************@TK2MSFTNGP11.phx.gbl...
Thanks for your reply, Mattias.

If the offset is relative to the beginning of the union struct rather than the containing struct, then the idea of UnionData1 and UnionData2

occupying
the same memory location is incorrect, isn't it?

To clarify matters, I wanted to have a data structure, TopStruct, that
contained some data that will be always populated (AlwaysContainsData
struct) by the data stream, and other data that would populate one of the union structs or the other (UnionData1 or UnionData2), but not both.

Hence,
I don't need to allocate memory for more than one union struct at a time, though I need all the members within it.

Can I accomplish this?
-Mike
"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:e$**************@TK2MSFTNGP12.phx.gbl...
Mike,

>Essentially, I don't know if the FieldOffset attribute applies to the

struct
>in which it's called, e.g. UnionData1, or to the top-level struct,
>TopStruct:

The offset is relative to the beginning of the "union" struct itself,
not any containing type.

Note that declaring a type nested inside another type does not
automatically give you a member of that nested type in the containing
type. Specifically, the TopStruct as it's written right now doesn't
have any members.

Mattias

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



Nov 15 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.