Byte array to known structure

S

Stan

Hi,

In my file I store data of known structure types.
Currently I am reading from file, storing into a byte
array, and then do a manual conversion from array to
structure by parsing all the bytes. Is there an easy way
to just tell C# that some byte array is actually of
structure MyStruct? It just seems like a waste since I
end up w/ two copies of my structure: the final product
and the byte array... Thanks.

+ Stan +
 
C

Chris Tacke, eMVP

I'm a bit confused - the structure can be nothing but pointers to locations
in a byte array if you so choose, so it's only one byte array and then
properties to access certain points. Take a look at many of the classes and
structs used by the OpenNETCF libraries for examples.

-Chris
 
J

John

What i think he means is can you do something like a blind cast (C++) or a
memcopy with the pointers (VB) so that the struct variable points directly
to the byte array.

I would like to know too :)
 
C

Chris Tacke, eMVP

Take a look at the SYSTEMTIME class implementation in OpenNETCF.WinAPI - it
(and several other classes) does exactly what you want.
 
C

Chris Tacke, eMVP

No, because the memory manager would f that all up if it moved the byte
array. If you look at the SYSTEMTIME class in the OpenNETCF stuff, it holds
a single internal variable, which is a byte array. It then has properties
that map to the "member" names which cast segments of that byte array to the
type that the property returns. With a couple operators, you can easily
create a byte array from the class or a class from a byte array, which
allows you to directly manipulate the bytes if you desire.
 
S

Stan

hmm.. perhaps I am looking at the wrong implementation,
but the one I see simply parses some string and tries to
fill in the parameters..

What I would like to do is go from file directly to
structure (avoiding as much intermediate buffers as
necessary). For instance, I am using FileStream in
the .NET CF. It allows me to read from file and place the
information into a Byte array.

Let's say I have an array of SYSTEMTIME structures (say
16 bytes each) that I'd like to fill in. I know the file
I'm reading has the exact/correct layout and has 5
SYSTEMTIME structures. Since I see that FileStream only
provides me with functions to read into a byte array, I
create a byte array of length (5*16) and read in all the
data. Is there a way (as John said) to "cast" this byte
array as an array of SYSTEMTIME structures? Or is there
an even better way? Right now it just seems like I have
to create yet another array with the explicit
(SYSTEMTIME) type and manually parse the Byte array, not
only taking time but potentially twice the memory...
Thanks.
 
C

Chris Tacke, eMVP

Sure. Let's look at a simple example (this is totally in this email editor,
so intellisnese, etc. are missing and I might have erros, but you'll get the
idea).

Let's assume we have a struct Foo with 2 DWORD members, X and Y.
sequentially they would be an 8-byte array with X followed by Y. The
following class has one copy of the data, properties that access those
bytes, a constructor and an operator that allows you to create a Foo from a
byte array (pulled from from your stream read) and an operator to get a
Foo's byte array (send it to your stream write).

public class Foo
{
private byte[] m_bytes = new byte[8];

// ctors
public Foo(){}
public Foo(byte[] bytes) { Buffer.BlockCopy(m_bytes, bytes, 0); }

// properties
public uint X
{
get{ return BitConverter.ToUInt32(m_bytes[0]); }
set{ Buffer.BlockCopy(m_bytes, BitConverter.GetBits(value), 0); }
}
public uint Y
{
get{ return BitConverter.ToUInt32(m_bytes[4]); }
set{ Buffer.BlockCopy(m_bytes, BitConverter.GetBits(value), 4); }
}

// operators
public static implicit operator byte[](Foo f)
{
return f.m_bytes;
}
public static implicit operator Foo(byte[] bytes)
{
return new Foo(bytes);
}
}

Does that make sense?

-Chris
 
J

John

Sorry to say this (no offense), but thats still way harder than VB/C++.
There must be an easier, less manual way. I can't imagine they'd take such a
step backwards
Chris Tacke said:
Sure. Let's look at a simple example (this is totally in this email editor,
so intellisnese, etc. are missing and I might have erros, but you'll get the
idea).

Let's assume we have a struct Foo with 2 DWORD members, X and Y.
sequentially they would be an 8-byte array with X followed by Y. The
following class has one copy of the data, properties that access those
bytes, a constructor and an operator that allows you to create a Foo from a
byte array (pulled from from your stream read) and an operator to get a
Foo's byte array (send it to your stream write).

public class Foo
{
private byte[] m_bytes = new byte[8];

// ctors
public Foo(){}
public Foo(byte[] bytes) { Buffer.BlockCopy(m_bytes, bytes, 0); }

// properties
public uint X
{
get{ return BitConverter.ToUInt32(m_bytes[0]); }
set{ Buffer.BlockCopy(m_bytes, BitConverter.GetBits(value), 0); }
}
public uint Y
{
get{ return BitConverter.ToUInt32(m_bytes[4]); }
set{ Buffer.BlockCopy(m_bytes, BitConverter.GetBits(value), 4); }
}

// operators
public static implicit operator byte[](Foo f)
{
return f.m_bytes;
}
public static implicit operator Foo(byte[] bytes)
{
return new Foo(bytes);
}
}

Does that make sense?

-Chris


Stan said:
hmm.. perhaps I am looking at the wrong implementation,
but the one I see simply parses some string and tries to
fill in the parameters..

What I would like to do is go from file directly to
structure (avoiding as much intermediate buffers as
necessary). For instance, I am using FileStream in
the .NET CF. It allows me to read from file and place the
information into a Byte array.

Let's say I have an array of SYSTEMTIME structures (say
16 bytes each) that I'd like to fill in. I know the file
I'm reading has the exact/correct layout and has 5
SYSTEMTIME structures. Since I see that FileStream only
provides me with functions to read into a byte array, I
create a byte array of length (5*16) and read in all the
data. Is there a way (as John said) to "cast" this byte
array as an array of SYSTEMTIME structures? Or is there
an even better way? Right now it just seems like I have
to create yet another array with the explicit
(SYSTEMTIME) type and manually parse the Byte array, not
only taking time but potentially twice the memory...
Thanks.
 
C

Chris Tacke, eMVP

That's hard? It took me less than 5 minutes. Admittedly it would be nice
to just copy the memory, but the memory management model in .NET makes that
way too dangerous, and getting it to work safely would be way more work.
The methodology above works well and I've not seen anything else that will
work well with P/Invokes that require structures.

--
Chris Tacke, eMVP
Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net

John said:
Sorry to say this (no offense), but thats still way harder than VB/C++.
There must be an easier, less manual way. I can't imagine they'd take such a
step backwards
Chris Tacke said:
Sure. Let's look at a simple example (this is totally in this email editor,
so intellisnese, etc. are missing and I might have erros, but you'll get the
idea).

Let's assume we have a struct Foo with 2 DWORD members, X and Y.
sequentially they would be an 8-byte array with X followed by Y. The
following class has one copy of the data, properties that access those
bytes, a constructor and an operator that allows you to create a Foo
from
a
byte array (pulled from from your stream read) and an operator to get a
Foo's byte array (send it to your stream write).

public class Foo
{
private byte[] m_bytes = new byte[8];

// ctors
public Foo(){}
public Foo(byte[] bytes) { Buffer.BlockCopy(m_bytes, bytes, 0); }

// properties
public uint X
{
get{ return BitConverter.ToUInt32(m_bytes[0]); }
set{ Buffer.BlockCopy(m_bytes, BitConverter.GetBits(value), 0); }
}
public uint Y
{
get{ return BitConverter.ToUInt32(m_bytes[4]); }
set{ Buffer.BlockCopy(m_bytes, BitConverter.GetBits(value), 4); }
}

// operators
public static implicit operator byte[](Foo f)
{
return f.m_bytes;
}
public static implicit operator Foo(byte[] bytes)
{
return new Foo(bytes);
}
}

Does that make sense?

-Chris


Stan said:
hmm.. perhaps I am looking at the wrong implementation,
but the one I see simply parses some string and tries to
fill in the parameters..

What I would like to do is go from file directly to
structure (avoiding as much intermediate buffers as
necessary). For instance, I am using FileStream in
the .NET CF. It allows me to read from file and place the
information into a Byte array.

Let's say I have an array of SYSTEMTIME structures (say
16 bytes each) that I'd like to fill in. I know the file
I'm reading has the exact/correct layout and has 5
SYSTEMTIME structures. Since I see that FileStream only
provides me with functions to read into a byte array, I
create a byte array of length (5*16) and read in all the
data. Is there a way (as John said) to "cast" this byte
array as an array of SYSTEMTIME structures? Or is there
an even better way? Right now it just seems like I have
to create yet another array with the explicit
(SYSTEMTIME) type and manually parse the Byte array, not
only taking time but potentially twice the memory...
Thanks.


-----Original Message-----
Take a look at the SYSTEMTIME class implementation in
OpenNETCF.WinAPI - it
(and several other classes) does exactly what you want.

--
Chris Tacke, eMVP
Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net

Hi,

In my file I store data of known structure types.
Currently I am reading from file, storing into a byte
array, and then do a manual conversion from array to
structure by parsing all the bytes. Is there an easy
way
to just tell C# that some byte array is actually of
structure MyStruct? It just seems like a waste since I
end up w/ two copies of my structure: the final product
and the byte array... Thanks.

+ Stan +


.
 

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