473,390 Members | 1,329 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,390 software developers and data experts.

PtrToStructure for unknown structure?

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
6 4831
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Mateusz [PEYN] Adamus | last post by:
Hi First of all please let me know if there is some other, more suitable group for this news - TIA :-) Now, my problem. I'm writing an C# application in which I'm using some functions from...
1
by: alfacom | last post by:
Hi, I have two C++ structures like these : typedef struct answer_series_item { int32_t contract_size_i; int32_t price_quot_factor_i; char ins_id_s ; char isin_code_s ; uint8_t suspended_c;
1
by: Ken Allen | last post by:
The documentation is not clear on the exact behaviour of the Marshal.PtrToStructure method and whether it copies the contents of the IntPtr region to a new managed object or whether it creates the...
2
by: Andre | last post by:
Hi, I have a question about Marshal.PtrToStructure method. I have a function Func() in unmanaged C++ which returns a pointer to a structure Str which is held on the unmanged site: Str* a =...
3
by: Tyron | last post by:
I want to get the Position of the Mouse when the User click in the non-client area of a Window. WM_NCLBUTTONDOWN seems to be the right Message for this - and the LParam contains a POINTS struct of...
4
by: C Learner | last post by:
Hi, I have an application which is using a dll written in C++. When the program go to the function below, it would raise an NullReferenceException at the line of PtrToStructure. public bool...
1
by: Jay | last post by:
Hi, In my application, C++ dll is posting some message,which is processed by a form in C# ,where I use Message.Lparam to convert it in structure using Marshal.PtrToStructure() mehtod ,but it...
1
by: spamacon | last post by:
Hello, I have a strange situation using .Net FW 1.1. I want to use Marshal.PtrToStructure to fill the structure below. The first 3 fields get filled correctly: ulStruct describes how big the...
1
by: Suja | last post by:
Hi All, I have a WIN32 DLL which pass some information to a .NET based application via the windows messages. When I try to convert this data in the managed code, I am getting junk data. Does any...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.