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

cast from "array of byte" to "array of struct"

P: n/a
I have a C# method that reads Binary data (BLOB type) from a database
and returns the data an array of bytes
(i.e byte[] outbyte = new byte[bufferSize];).

The BLOB column is saved into the database by a C program (UNIX) as an
array of "struct point" where

struct point //C structure
{
int Time; //32 bits
float Value; //32 bits
};
How can I cast the byte array read in the C# method to an array of
Sample where

public struct Sample //C# structure
{
System.Int32 Time; //32 bits
System.Single Value; //32 bits
}
?

In C/C++ this is extremely simple using pointers, but which is the
best way of doing this in C#?
Nov 15 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
C# - and most .NET languages for that matter - are very strongly typed
languages. The data type integrity and strict interpretation not only cut
down on bugs, but allow for better code security. However, that means you
cannot cast arbitrary buffers to or from other datatypes.
You will have to create a separate variable of the struct type, then convert
and copy the bytes to the struct's members.
You can use System.BitConverter to help you do the byte-to-other-type
conversion. However, since your data was created by a Unix program, there is
a real chance that you will have issues concerning big-endian vs. little
endian integer types - in other words, the high-low byte orders for your int
may be reversed. If that's the case, you cannot use BitConverter, and must
do manual bit shifting on the bytes to assemble the int part of your
structure.
As an alternative, you can pin the byte array and use the
System.Runtime.Interop.Marshal.UnsafeAddrOfPinnedA rrayElement in conjunction
with System.Interop.Marshal.PtrToStruct. But, realize that in either case,
you creating a copy of the data from the buffer, and not merely casting the
buffer itself. That isn't possible unless you drop to Unsafe code blocks,
which I don't usually recommend. And more importantly, realize that this
method is still prone to the int endian problem. That being the case, your
best bet may be to just bite the bullet and do the manual bit shifting.

-Rob Teixeira [MVP]
"Pablo Gutierrez" <xp****@hotmail.com> wrote in message
news:2e**************************@posting.google.c om...
I have a C# method that reads Binary data (BLOB type) from a database
and returns the data an array of bytes
(i.e byte[] outbyte = new byte[bufferSize];).

The BLOB column is saved into the database by a C program (UNIX) as an
array of "struct point" where

struct point //C structure
{
int Time; //32 bits
float Value; //32 bits
};
How can I cast the byte array read in the C# method to an array of
Sample where

public struct Sample //C# structure
{
System.Int32 Time; //32 bits
System.Single Value; //32 bits
}
?

In C/C++ this is extremely simple using pointers, but which is the
best way of doing this in C#?

Nov 15 '05 #2

P: n/a
Rob Teixeira [MVP] wrote:
C# - and most .NET languages for that matter - are very strongly typed
languages. The data type integrity and strict interpretation not only cut
down on bugs, but allow for better code security. However, that means you
cannot cast arbitrary buffers to or from other datatypes.
You will have to create a separate variable of the struct type, then convert
and copy the bytes to the struct's members.
You can use System.BitConverter to help you do the byte-to-other-type
conversion. However, since your data was created by a Unix program, there is
a real chance that you will have issues concerning big-endian vs. little
endian integer types - in other words, the high-low byte orders for your int
may be reversed. If that's the case, you cannot use BitConverter, and must
do manual bit shifting on the bytes to assemble the int part of your
structure.
As an alternative, you can pin the byte array and use the
System.Runtime.Interop.Marshal.UnsafeAddrOfPinnedA rrayElement in conjunction
with System.Interop.Marshal.PtrToStruct. But, realize that in either case,
you creating a copy of the data from the buffer, and not merely casting the
buffer itself. That isn't possible unless you drop to Unsafe code blocks,
which I don't usually recommend. And more importantly, realize that this
method is still prone to the int endian problem. That being the case, your
best bet may be to just bite the bullet and do the manual bit shifting.

-Rob Teixeira [MVP]
Note that IPAddress.NetworkToHostOrder() will convert big-endian ints to
the native byte order.


"Pablo Gutierrez" <xp****@hotmail.com> wrote in message
news:2e**************************@posting.google.c om...
I have a C# method that reads Binary data (BLOB type) from a database
and returns the data an array of bytes
(i.e byte[] outbyte = new byte[bufferSize];).

The BLOB column is saved into the database by a C program (UNIX) as an
array of "struct point" where

struct point //C structure
{
int Time; //32 bits
float Value; //32 bits
};
How can I cast the byte array read in the C# method to an array of
Sample where

public struct Sample //C# structure
{
System.Int32 Time; //32 bits
System.Single Value; //32 bits
}
?

In C/C++ this is extremely simple using pointers, but which is the
best way of doing this in C#?


--
mikeb
Nov 15 '05 #3

P: n/a
> I have a C# method that reads Binary data (BLOB type) from a database
and returns the data an array of bytes
(i.e byte[] outbyte = new byte[bufferSize];).

How can I cast the byte array read in the C# method to an array of
Sample where

public struct Sample //C# structure
{
System.Int32 Time; //32 bits
System.Single Value; //32 bits
}

Something like this will convert a bytes a C# structure...
byte[] sourceData;
MyStruct destStruct;
int arrayIndex = 0;

GCHandle handle = GCHandle.Alloc(sourceData, GCHandleType.Pinned);
try
{
IntPtr buffer = handle.AddrOfPinnedObject();
buffer = (IntPtr)(buffer.ToInt32() +
(arrayIndex*Marshal.SizeOf(typeof(MyStruct))));
destStruct = (MyStruct)Marshal.PtrToStructure(buffer, typeof(MyStruct));
}
finally
{
handle.Free();
}
Nov 15 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.