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

PtrToStructure for unknown structure?

P: n/a
Hi,

Here, sample code where a byte array is used to fill a particular structure:

[...]

fs = File.OpenRead(path); // FileStream

BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();
b = new byte[(int)bfh.Size()];

fs.Read(b, 0, b.Length);
fixed (byte* pb = &b[0])
bfh = (BITMAPFILEHEADER)Marshal.PtrToStructure((IntPtr)p b, typeof(BITMAPFILEHEADER));

[...]

What I would like to have is a function capable of accepting an [in] byte array and an [out] unkown structure type.
Is that possible?

Thanks in advance,

Carles
Jun 27 '08 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Using a generic method that takes a type parameter:
public static unsafe T ByteArrayToStructure<T( byte [ ] array )
where T : struct
{
fixed ( byte* pb = &b [ 0 ] )
return ( T ) Marshal.PtrToStructure( (IntPtr)pb, typeof(T));
}

If you are using unsafe anyway, you dont need to use Marshal if you dont
want to,
you could cast it old C++ style if you want. Probably more efficient

Dennis Myren
"carles" <ca*********@gmail.comwrote in message
news:eo**************@TK2MSFTNGP02.phx.gbl...
Hi,

Here, sample code where a byte array is used to fill a particular structure:

[...]

fs = File.OpenRead(path); // FileStream

BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();
b = new byte[(int)bfh.Size()];

fs.Read(b, 0, b.Length);
fixed (byte* pb = &b[0])
bfh =
(BITMAPFILEHEADER)Marshal.PtrToStructure((IntPtr)p b,
typeof(BITMAPFILEHEADER));

[...]

What I would like to have is a function capable of accepting an [in] byte
array and an [out] unkown structure type.
Is that possible?

Thanks in advance,

Carles
Jun 27 '08 #2

P: n/a
Thanks a lot,

New on "C#" (and C)... could you please tell me how to do it old C++ style?

Carles

"baretta" <ba******@gmail.comha escrit al missatge del grup de discussió:
ux*************@TK2MSFTNGP04.phx.gbl...
Using a generic method that takes a type parameter:
public static unsafe T ByteArrayToStructure<T( byte [ ] array )
where T : struct
{
fixed ( byte* pb = &b [ 0 ] )
return ( T ) Marshal.PtrToStructure( (IntPtr)pb, typeof(T));
}

If you are using unsafe anyway, you dont need to use Marshal if you dont
want to,
you could cast it old C++ style if you want. Probably more efficient

Dennis Myren
"carles" <ca*********@gmail.comwrote in message
news:eo**************@TK2MSFTNGP02.phx.gbl...
Hi,

Here, sample code where a byte array is used to fill a particular
structure:

[...]

fs = File.OpenRead(path); // FileStream

BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();
b = new byte[(int)bfh.Size()];

fs.Read(b, 0, b.Length);
fixed (byte* pb = &b[0])
bfh =
(BITMAPFILEHEADER)Marshal.PtrToStructure((IntPtr)p b,
typeof(BITMAPFILEHEADER));

[...]

What I would like to have is a function capable of accepting an [in] byte
array and an [out] unkown structure type.
Is that possible?

Thanks in advance,

Carles

Jun 27 '08 #3

P: n/a
I am sorry if i was misleading.
Actually it is not possible to use a C-style approach,
it would only work with structure whose types we know during compile time.

This approach was what i was thinking about(without really thinking):
public static unsafe T ByteArrayToStructure<T( byte [ ] buffer )
where T : struct
{
fixed ( byte* pBuff = buffer )
{
return *( T* ) pBuff;
}
}

But actually, although we limit T to being a struct using where keyword,
we cannot at this point guarantee that a pointer to this type can be
obtained at runtime.
It can only be obtained if a struct has only primitive fields, and this we
cant guarantee at this point.
If we would change the return value to a known struct made up completely of
primitives it would compile.
This one is totally managed. At least it compiles:
public static T ByteArrayToStructure<T( byte [ ] buffer )
where T : struct
{
IntPtr ptr = Marshal.AllocHGlobal ( buffer.Length );
Marshal.Copy ( buffer, 0x0, ptr, buffer.Length );
T ret = ( T ) Marshal.PtrToStructure ( ptr, typeof ( T ) );

Marshal.FreeHGlobal ( ptr );
return ret;
}

and you will use it like this:
BITMAPFILEHEADER header = ByteArrayToStructure<BITMAPFILEHEADER(
yourByteArray );
I would recommend modifying ByteArrayToStructure, so that it takes the
System.IO.Stream as parameter rather than the byte array.
Otherwise, it is assumed that the buffer passed in is of the correct size
already(which is the size of the struct).
It is better if this is handled by the function.

So, this is the final result:
public static T ReadStructure<T( Stream stream )
where T : struct
{
byte [ ] buff = new byte [ Marshal.SizeOf ( typeof ( T ) ) ];
IntPtr ptr = Marshal.AllocHGlobal ( buff.Length );
Marshal.Copy ( buff, 0x0, ptr, buff.Length );
T ret = ( T ) Marshal.PtrToStructure ( ptr, typeof ( T ) );

Marshal.FreeHGlobal ( ptr );
return ret;
}
Dennis Myren
"carles" <ca*********@gmail.comskrev i melding
news:eK**************@TK2MSFTNGP06.phx.gbl...
Thanks a lot,

New on "C#" (and C)... could you please tell me how to do it old C++
style?

Carles

"baretta" <ba******@gmail.comha escrit al missatge del grup de
discussió: ux*************@TK2MSFTNGP04.phx.gbl...
>Using a generic method that takes a type parameter:
public static unsafe T ByteArrayToStructure<T( byte [ ] array )
where T : struct
{
fixed ( byte* pb = &b [ 0 ] )
return ( T ) Marshal.PtrToStructure( (IntPtr)pb, typeof(T));
}

If you are using unsafe anyway, you dont need to use Marshal if you dont
want to,
you could cast it old C++ style if you want. Probably more efficient

Dennis Myren
"carles" <ca*********@gmail.comwrote in message
news:eo**************@TK2MSFTNGP02.phx.gbl...
Hi,

Here, sample code where a byte array is used to fill a particular
structure:

[...]

fs = File.OpenRead(path); // FileStream

BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();
b = new byte[(int)bfh.Size()];

fs.Read(b, 0, b.Length);
fixed (byte* pb = &b[0])
bfh =
(BITMAPFILEHEADER)Marshal.PtrToStructure((IntPtr) pb,
typeof(BITMAPFILEHEADER));

[...]

What I would like to have is a function capable of accepting an [in] byte
array and an [out] unkown structure type.
Is that possible?

Thanks in advance,

Carles

Jun 27 '08 #4

P: n/a
Thanks again.
Really enlightening answer.

One thing: Marshal.SizeOf() seems to return 32-bit (depends on what?)
aligned sizes.
In my case, I sequentially read several structures from file, so I need to
exactly read structure byte-lenghts (ie, BITMAPFILEHEADER is 14
byte-lenght). I decided to add a static Size() function for each structure
definition, returning its byte-lenght size. Error handling is done at time
to read from file.

So, another question could be next: how to determine byte-length size of the
passed (unknown) structure. This would allow to compact ByteArrayToStructure
to your suggested final approach, sizing buffer and reading from stream
inside same function.

Carles

"baretta" <ba******@gmail.comha escrit al missatge del grup de discussió:
Oz*************@TK2MSFTNGP05.phx.gbl...
>I am sorry if i was misleading.
Actually it is not possible to use a C-style approach,
it would only work with structure whose types we know during compile time.

This approach was what i was thinking about(without really thinking):
public static unsafe T ByteArrayToStructure<T( byte [ ] buffer )
where T : struct
{
fixed ( byte* pBuff = buffer )
{
return *( T* ) pBuff;
}
}

But actually, although we limit T to being a struct using where keyword,
we cannot at this point guarantee that a pointer to this type can be
obtained at runtime.
It can only be obtained if a struct has only primitive fields, and this we
cant guarantee at this point.
If we would change the return value to a known struct made up completely
of primitives it would compile.
This one is totally managed. At least it compiles:
public static T ByteArrayToStructure<T( byte [ ] buffer )
where T : struct
{
IntPtr ptr = Marshal.AllocHGlobal ( buffer.Length );
Marshal.Copy ( buffer, 0x0, ptr, buffer.Length );
T ret = ( T ) Marshal.PtrToStructure ( ptr, typeof ( T ) );

Marshal.FreeHGlobal ( ptr );
return ret;
}

and you will use it like this:
BITMAPFILEHEADER header = ByteArrayToStructure<BITMAPFILEHEADER(
yourByteArray );
I would recommend modifying ByteArrayToStructure, so that it takes the
System.IO.Stream as parameter rather than the byte array.
Otherwise, it is assumed that the buffer passed in is of the correct size
already(which is the size of the struct).
It is better if this is handled by the function.

So, this is the final result:
public static T ReadStructure<T( Stream stream )
where T : struct
{
byte [ ] buff = new byte [ Marshal.SizeOf ( typeof ( T ) ) ];
IntPtr ptr = Marshal.AllocHGlobal ( buff.Length );
Marshal.Copy ( buff, 0x0, ptr, buff.Length );
T ret = ( T ) Marshal.PtrToStructure ( ptr, typeof ( T ) );

Marshal.FreeHGlobal ( ptr );
return ret;
}
Dennis Myren
"carles" <ca*********@gmail.comskrev i melding
news:eK**************@TK2MSFTNGP06.phx.gbl...
>Thanks a lot,

New on "C#" (and C)... could you please tell me how to do it old C++
style?

Carles

"baretta" <ba******@gmail.comha escrit al missatge del grup de
discussió: ux*************@TK2MSFTNGP04.phx.gbl...
>>Using a generic method that takes a type parameter:
public static unsafe T ByteArrayToStructure<T( byte [ ] array )
where T : struct
{
fixed ( byte* pb = &b [ 0 ] )
return ( T ) Marshal.PtrToStructure( (IntPtr)pb, typeof(T));
}

If you are using unsafe anyway, you dont need to use Marshal if you dont
want to,
you could cast it old C++ style if you want. Probably more efficient

Dennis Myren
"carles" <ca*********@gmail.comwrote in message
news:eo**************@TK2MSFTNGP02.phx.gbl...
Hi,

Here, sample code where a byte array is used to fill a particular
structure:

[...]

fs = File.OpenRead(path); // FileStream

BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();
b = new byte[(int)bfh.Size()];

fs.Read(b, 0, b.Length);
fixed (byte* pb = &b[0])
bfh =
(BITMAPFILEHEADER)Marshal.PtrToStructure((IntPtr )pb,
typeof(BITMAPFILEHEADER));

[...]

What I would like to have is a function capable of accepting an [in]
byte array and an [out] unkown structure type.
Is that possible?

Thanks in advance,

Carles


Jun 27 '08 #5

P: n/a
At structure definition, for example:

[StructLayout(LayoutKind.Sequential, Pack=1)]
private struct BITMAPFILEHEADER
{
public ushort bfType;
public uint bfSize;
public short bfReserved1;
public short bfReserved2;
public uint bfOffBits;
}

adding that 'Pack=1 specification', no padding is done, and 'packed' size is
returned, 14.
Hope nothing more has to be taken into account.

Carles
"carles" <ca*********@gmail.comha escrit al missatge del grup de
discussió: %2****************@TK2MSFTNGP05.phx.gbl...
Thanks again.
Really enlightening answer.

One thing: Marshal.SizeOf() seems to return 32-bit (depends on what?)
aligned sizes.
In my case, I sequentially read several structures from file, so I need to
exactly read structure byte-lenghts (ie, BITMAPFILEHEADER is 14
byte-lenght). I decided to add a static Size() function for each structure
definition, returning its byte-lenght size. Error handling is done at time
to read from file.

So, another question could be next: how to determine byte-length size of
the passed (unknown) structure. This would allow to compact
ByteArrayToStructure to your suggested final approach, sizing buffer and
reading from stream inside same function.

Carles

"baretta" <ba******@gmail.comha escrit al missatge del grup de
discussió: Oz*************@TK2MSFTNGP05.phx.gbl...
>>I am sorry if i was misleading.
Actually it is not possible to use a C-style approach,
it would only work with structure whose types we know during compile
time.

This approach was what i was thinking about(without really thinking):
public static unsafe T ByteArrayToStructure<T( byte [ ] buffer )
where T : struct
{
fixed ( byte* pBuff = buffer )
{
return *( T* ) pBuff;
}
}

But actually, although we limit T to being a struct using where keyword,
we cannot at this point guarantee that a pointer to this type can be
obtained at runtime.
It can only be obtained if a struct has only primitive fields, and this
we cant guarantee at this point.
If we would change the return value to a known struct made up completely
of primitives it would compile.
This one is totally managed. At least it compiles:
public static T ByteArrayToStructure<T( byte [ ] buffer )
where T : struct
{
IntPtr ptr = Marshal.AllocHGlobal ( buffer.Length );
Marshal.Copy ( buffer, 0x0, ptr, buffer.Length );
T ret = ( T ) Marshal.PtrToStructure ( ptr, typeof ( T ) );

Marshal.FreeHGlobal ( ptr );
return ret;
}

and you will use it like this:
BITMAPFILEHEADER header = ByteArrayToStructure<BITMAPFILEHEADER(
yourByteArray );
I would recommend modifying ByteArrayToStructure, so that it takes the
System.IO.Stream as parameter rather than the byte array.
Otherwise, it is assumed that the buffer passed in is of the correct size
already(which is the size of the struct).
It is better if this is handled by the function.

So, this is the final result:
public static T ReadStructure<T( Stream stream )
where T : struct
{
byte [ ] buff = new byte [ Marshal.SizeOf ( typeof ( T ) ) ];
IntPtr ptr = Marshal.AllocHGlobal ( buff.Length );
Marshal.Copy ( buff, 0x0, ptr, buff.Length );
T ret = ( T ) Marshal.PtrToStructure ( ptr, typeof ( T ) );

Marshal.FreeHGlobal ( ptr );
return ret;
}
Dennis Myren
"carles" <ca*********@gmail.comskrev i melding
news:eK**************@TK2MSFTNGP06.phx.gbl...
>>Thanks a lot,

New on "C#" (and C)... could you please tell me how to do it old C++
style?

Carles

"baretta" <ba******@gmail.comha escrit al missatge del grup de
discussió: ux*************@TK2MSFTNGP04.phx.gbl...
Using a generic method that takes a type parameter:
public static unsafe T ByteArrayToStructure<T( byte [ ] array )
where T : struct
{
fixed ( byte* pb = &b [ 0 ] )
return ( T ) Marshal.PtrToStructure( (IntPtr)pb, typeof(T));
}

If you are using unsafe anyway, you dont need to use Marshal if you
dont want to,
you could cast it old C++ style if you want. Probably more efficient

Dennis Myren
"carles" <ca*********@gmail.comwrote in message
news:eo**************@TK2MSFTNGP02.phx.gbl...
Hi,

Here, sample code where a byte array is used to fill a particular
structure:

[...]

fs = File.OpenRead(path); // FileStream

BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();
b = new byte[(int)bfh.Size()];

fs.Read(b, 0, b.Length);
fixed (byte* pb = &b[0])
bfh =
(BITMAPFILEHEADER)Marshal.PtrToStructure((IntPt r)pb,
typeof(BITMAPFILEHEADER));

[...]

What I would like to have is a function capable of accepting an [in]
byte array and an [out] unkown structure type.
Is that possible?

Thanks in advance,

Carles


Jun 27 '08 #6

P: n/a
That is correct, i have used both Marshal.SizeOf and the unsafe keyword
sizeof myself to retrieve sizes of structures correctly.
All my structures has the Pack=1 property set.

You should be OK.


"carles" <ca*********@gmail.comwrote in message
news:uX**************@TK2MSFTNGP05.phx.gbl...
At structure definition, for example:

[StructLayout(LayoutKind.Sequential, Pack=1)]
private struct BITMAPFILEHEADER
{
public ushort bfType;
public uint bfSize;
public short bfReserved1;
public short bfReserved2;
public uint bfOffBits;
}

adding that 'Pack=1 specification', no padding is done, and 'packed' size
is returned, 14.
Hope nothing more has to be taken into account.

Carles
"carles" <ca*********@gmail.comha escrit al missatge del grup de
discussió: %2****************@TK2MSFTNGP05.phx.gbl...
>Thanks again.
Really enlightening answer.

One thing: Marshal.SizeOf() seems to return 32-bit (depends on what?)
aligned sizes.
In my case, I sequentially read several structures from file, so I need
to exactly read structure byte-lenghts (ie, BITMAPFILEHEADER is 14
byte-lenght). I decided to add a static Size() function for each
structure definition, returning its byte-lenght size. Error handling is
done at time to read from file.

So, another question could be next: how to determine byte-length size of
the passed (unknown) structure. This would allow to compact
ByteArrayToStructure to your suggested final approach, sizing buffer and
reading from stream inside same function.

Carles

"baretta" <ba******@gmail.comha escrit al missatge del grup de
discussió: Oz*************@TK2MSFTNGP05.phx.gbl...
>>>I am sorry if i was misleading.
Actually it is not possible to use a C-style approach,
it would only work with structure whose types we know during compile
time.

This approach was what i was thinking about(without really thinking):
public static unsafe T ByteArrayToStructure<T( byte [ ] buffer )
where T : struct
{
fixed ( byte* pBuff = buffer )
{
return *( T* ) pBuff;
}
}

But actually, although we limit T to being a struct using where keyword,
we cannot at this point guarantee that a pointer to this type can be
obtained at runtime.
It can only be obtained if a struct has only primitive fields, and this
we cant guarantee at this point.
If we would change the return value to a known struct made up completely
of primitives it would compile.
This one is totally managed. At least it compiles:
public static T ByteArrayToStructure<T( byte [ ] buffer )
where T : struct
{
IntPtr ptr = Marshal.AllocHGlobal ( buffer.Length );
Marshal.Copy ( buffer, 0x0, ptr, buffer.Length );
T ret = ( T ) Marshal.PtrToStructure ( ptr, typeof ( T ) );

Marshal.FreeHGlobal ( ptr );
return ret;
}

and you will use it like this:
BITMAPFILEHEADER header = ByteArrayToStructure<BITMAPFILEHEADER(
yourByteArray );
I would recommend modifying ByteArrayToStructure, so that it takes the
System.IO.Stream as parameter rather than the byte array.
Otherwise, it is assumed that the buffer passed in is of the correct
size already(which is the size of the struct).
It is better if this is handled by the function.

So, this is the final result:
public static T ReadStructure<T( Stream stream )
where T : struct
{
byte [ ] buff = new byte [ Marshal.SizeOf ( typeof ( T ) ) ];
IntPtr ptr = Marshal.AllocHGlobal ( buff.Length );
Marshal.Copy ( buff, 0x0, ptr, buff.Length );
T ret = ( T ) Marshal.PtrToStructure ( ptr, typeof ( T ) );

Marshal.FreeHGlobal ( ptr );
return ret;
}
Dennis Myren
"carles" <ca*********@gmail.comskrev i melding
news:eK**************@TK2MSFTNGP06.phx.gbl...
Thanks a lot,

New on "C#" (and C)... could you please tell me how to do it old C++
style?

Carles

"baretta" <ba******@gmail.comha escrit al missatge del grup de
discussió: ux*************@TK2MSFTNGP04.phx.gbl...
Using a generic method that takes a type parameter:
public static unsafe T ByteArrayToStructure<T( byte [ ] array )
where T : struct
{
fixed ( byte* pb = &b [ 0 ] )
return ( T ) Marshal.PtrToStructure( (IntPtr)pb, typeof(T));
}
>
If you are using unsafe anyway, you dont need to use Marshal if you
dont want to,
you could cast it old C++ style if you want. Probably more efficient
>
Dennis Myren
>
>
"carles" <ca*********@gmail.comwrote in message
news:eo**************@TK2MSFTNGP02.phx.gbl.. .
Hi,
>
Here, sample code where a byte array is used to fill a particular
structure:
>
[...]
>
fs = File.OpenRead(path); // FileStream
>
BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();
b = new byte[(int)bfh.Size()];
>
fs.Read(b, 0, b.Length);
fixed (byte* pb = &b[0])
bfh =
(BITMAPFILEHEADER)Marshal.PtrToStructure((IntP tr)pb,
typeof(BITMAPFILEHEADER));
>
[...]
>
What I would like to have is a function capable of accepting an [in]
byte array and an [out] unkown structure type.
Is that possible?
>
Thanks in advance,
>
Carles
>



Jun 27 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.