I am a total newb at .net, and I have not been able to search out a best
practice answer to what must be a common problem.
My app must process binary data from a UDP socket, a MSMQ queue and a file.
In C, the data is in nested structs, with mixed types, floats, ints, char
arrays, int arrays, variable length arrays of structs etc.
My preference would be to access the data in a similar fashion to C, casting
the byte array of received data to the struct I want, and then sending out
the struct when it is time to transmit.
How can I format a struct to be able to mimic legacy structs, especially
with arrays? I see how I can do it for marshalled code, with [ MarshalAs(
UnmanagedType.ByValArray, SizeConst=XX )] attribute, but does that only work
with unmanaged code?
Thanks,
Seth
John Vottero - 25 Mar 2008 19:35 GMT
>I am a total newb at .net, and I have not been able to search out a best
> practice answer to what must be a common problem.
[quoted text clipped - 14 lines]
> work
> with unmanaged code?
Define your structs using the StructLayout and MarshlAs attributes then use
Marshal.UnsafeAddrOfPinnedArrayElement() and Marshal.PtrToStructure() to
convert from an array of bytes to a managed object. The Marshal class has a
number of useful methods.
SethInMI - 25 Mar 2008 20:09 GMT
I understand how to at least get started using the Marshal attributes in
defining my struct in C#, but I am still I think missing one step. Does
marshalling work if no unmanaged code or memory is accessed?
here is my pseudo code, where myStruct is defined using LayoutSequential and
appropriate Marshalling attributes to mimic the layout of legacy C struct.
Byte[] RawData = sock.Receive(ref RawAddr);
If (RawData.Length == Marshal.SizeOf(myStruct) {
Convert RawData into myStruct (using marshalling? just a cast?)
}
> >I am a total newb at .net, and I have not been able to search out a best
> > practice answer to what must be a common problem.
[quoted text clipped - 19 lines]
> convert from an array of bytes to a managed object. The Marshal class has a
> number of useful methods.
John Vottero - 26 Mar 2008 16:02 GMT
>I understand how to at least get started using the Marshal attributes in
> defining my struct in C#, but I am still I think missing one step. Does
[quoted text clipped - 8 lines]
> Convert RawData into myStruct (using marshalling? just a cast?)
> }
To convert RawData into myStruct, you would do something like:
IntPtr adr = Marshal.UnsafeAddrOfPinnedArrayElement(RawData, 0);
MyStruct myStruct = Marshal.PtrToStructure(adr, typeof(MyStruct));
When you use the LayoutSequential and Marshaling attributes, you aren't
actually changing the structure, you're just providing instructions that are
used when marshaling the structure to/from unmanaged bytes.
SethInMI - 26 Mar 2008 16:29 GMT
Thanks John.
You mentioned UnsafeAddrOfPinnedArrayElement in your first post, I just
didn't pick up how to use it.
> >I understand how to at least get started using the Marshal attributes in
> > defining my struct in C#, but I am still I think missing one step. Does
[quoted text clipped - 17 lines]
> actually changing the structure, you're just providing instructions that are
> used when marshaling the structure to/from unmanaged bytes.
Ben Voigt [C++ MVP] - 26 Mar 2008 21:06 GMT
> I am a total newb at .net, and I have not been able to search out a
> best practice answer to what must be a common problem.
[quoted text clipped - 11 lines]
> with [ MarshalAs( UnmanagedType.ByValArray, SizeConst=XX )]
> attribute, but does that only work with unmanaged code?
Use the BitConverter class to convert each member, one at a time.
> Thanks,
>
> Seth