unions in C#

B

Brian

I have been porting some C++ code to .net. I know C# doesn't have unions but
in order to write a particular algorythm efficiently i have a need to
address memory in in 2 different ways. As individual elements and also as an
array. I have tried the following (along with several variations) and none
work. Anyone have an alternative to what I am trying to do? The problem
comes when I want to have the int array occupy the same space as the 6 ints
defined above it. I would even try an 'unsafe' block using the 'fixed'
method but am having trouble getting that to work also. Seems there might be
some conflict with the other attributes I require possibly.


[StructLayout(LayoutKind.Explicit, Size = 24)]
public class TRIANGLE

{

[FieldOffset(0)] public int a;

[FieldOffset(4)] public int b;

[FieldOffset(8)] public int c;

[FieldOffset(12)] public int a_to_b;

[FieldOffset(16)] public int b_to_c;

[FieldOffset(20)] public int c_to_a;

[FieldOffset(0)] public int[] tri_pnt;

}



Any help would be greatly appreciated.



thanks

brian
 
L

Lloyd Dupont

You could forget that kind of implementation.
See .NET help for more information:
ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxinterop/html/96a62265-dcf9-4608-bc0a-1f762ab9f48e.htm

Meanwhile you could try this C# developer friendly code:
public class Triangle : ICollection
{
public int A;
public int B;
public int C;
public int this[int index]
{
get
{
switch(index)
{
case 0:
return A;
case 1:
return B;
case 2:
return C;
default:
throw new ArgumentOutOfRangeException("idnex");
}
}
set
{
switch(index)
{
case 0:
A = value;
case 1:
B = value;
case 2:
C = value;
default:
throw new ArgumentOutOfRangeException("idnex");
}
}
}
public int Count { get { return 3; } }
public IEnumerator GetEnumerator()
{
yield return A;
yield return B;
yield return C;
}
}
 
W

Willy Denoyette [MVP]

|I have been porting some C++ code to .net. I know C# doesn't have unions
but
| in order to write a particular algorythm efficiently i have a need to
| address memory in in 2 different ways. As individual elements and also as
an
| array. I have tried the following (along with several variations) and none
| work. Anyone have an alternative to what I am trying to do? The problem
| comes when I want to have the int array occupy the same space as the 6
ints
| defined above it. I would even try an 'unsafe' block using the 'fixed'
| method but am having trouble getting that to work also. Seems there might
be
| some conflict with the other attributes I require possibly.
|
|
| [StructLayout(LayoutKind.Explicit, Size = 24)]
| public class TRIANGLE
|
| {
|
| [FieldOffset(0)] public int a;
|
| [FieldOffset(4)] public int b;
|
| [FieldOffset(8)] public int c;
|
| [FieldOffset(12)] public int a_to_b;
|
| [FieldOffset(16)] public int b_to_c;
|
| [FieldOffset(20)] public int c_to_a;
|
| [FieldOffset(0)] public int[] tri_pnt;
|
| }
|
|
|
| Any help would be greatly appreciated.
|
|
|
| thanks
|
| brian
|
|

If you don't mind to introduce some unsafe context in your applications,
make your TRIANGLE a struct and declare your array of int's as fixed,
something like this will do:

{[StructLayout(LayoutKind.Explicit)]
public unsafe struct TRIANGLE
{
[FieldOffset(0)] public int a;
[FieldOffset(4)] public int b;
[FieldOffset(8)] public int c;
[FieldOffset(12)] public int a_to_b;
[FieldOffset(16)] public int b_to_c;
[FieldOffset(20)] public int c_to_a;
[FieldOffset(0)] public fixed int tri_pnt[6];
}

Note that you can't access fixed elements from safe context, nor can you
"foreach" variable of that type.

....
TRIANGLE t = new TRIANGLE();
t.a = 1; t.b = 2; t.c = 3; t.a_to_b = 4;
t.b_to_c = 5; t.c_to_a = 6;
int tSize = Marshal.SizeOf(t)/sizeof(int);
unsafe {
for(int i = 0; i < tSize; i++)
Console.WriteLine(t.tri_pnt);
}

Willy.
 
T

Thomas T. Veldhouse

Brian said:
I have been porting some C++ code to .net. I know C# doesn't have unions but
in order to write a particular algorythm efficiently i have a need to
address memory in in 2 different ways. As individual elements and also as an
array. I have tried the following (along with several variations) and none
work. Anyone have an alternative to what I am trying to do? The problem
comes when I want to have the int array occupy the same space as the 6 ints
defined above it. I would even try an 'unsafe' block using the 'fixed'
method but am having trouble getting that to work also. Seems there might be
some conflict with the other attributes I require possibly.


[StructLayout(LayoutKind.Explicit, Size = 24)]
public class TRIANGLE

{

[FieldOffset(0)] public int a;

[FieldOffset(4)] public int b;

[FieldOffset(8)] public int c;

[FieldOffset(12)] public int a_to_b;

[FieldOffset(16)] public int b_to_c;

[FieldOffset(20)] public int c_to_a;

[FieldOffset(0)] public int[] tri_pnt;

}



Any help would be greatly appreciated.

Brian ... take a look at the System.BitConverter class. You might be able to
get it to work in such a way to be useful to you. I do believe that it copies
the results, so you will constantly be thunking the data back and forth, but
it should be more efficient than some other methods. Nowhere near the
efficiency of a C++ union though.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top