![]() |
|
|||||||
| Notices |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Guest
Posts: n/a
|
Structure to Byte Array in VB.NET
I have been pulling my hair out with this and have searched and found
some solutions but I can't seem to get them to work as expected. I have a structure, which I have declared explicitly using <StructLayout(LayoutKind.Explicit)> The structure does contain some arrays, but it is something like this <StructLayout(LayoutKind.Explicit)> Public Structure TheStruct <FieldOffset(0)> Dim UpdateMode As Int16 <FieldOffset(2)> Dim TimeFrameCounter As Int16 <FieldOffset(4), VBFixedArray(7)> Dim AxisCommandedPosition() As Integer <FieldOffset(36), VBFixedArray(7)> Dim AxisEncoderPosition() As Integer <FieldOffset(68), VBFixedArray(7)> Dim AxisCommandedVelocity() As Integer <FieldOffset(100), VBFixedArray(7)> Dim AxisStatus() As Integer <FieldOffset(132)> Dim SystemStatus As Integer End Structure I need to use this as a byte array so I can send it over a ethernet socket (after manipulating it a bit) I have tried this: Dim myStruct as TheStruct Dim fsdata() As Byte ReDim fsdata(Marshal.SizeOf(myStruct) - 1) Dim ptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(myStruct)) 'get a pointer to myStruct Marshal.StructureToPtr(myStruct, ptr, True) 'copy myStruct from the heap pointer into fsdata array Marshal.Copy(ptr, fsdata, 0, Marshal.SizeOf(myStruct)) 'release the heap memory Marshal.FreeHGlobal(ptr) This sometimes works, but the line Marshal.StructureToPtr(myStruct, ptr, True) often crashes with a message "Attempted to read or write protected memory." If I change it to: Marshal.StructureToPtr(myStruct, ptr, False) It doesnt crash, but the data that ends up in the fsdata data is garbage - not myStruct. Is there a way to do this in vb.net that actually works? If I have a managed structure of a fixed size explicitly laid out, why do I have to marshal it through unmanaged memory to use it as a byte array? When I call Marshal.AllocHGlobal to get a pointer why would it give me a pointer to a protected memory area I can't use? Or is that what is happening? For now I have given up on using the structure and will just use a byte array. I will write some other functions to access the peices of the array as if it were a structure, but this is messy. Is there a better way? thanks. |
|
|
|
#2 |
|
Guest
Posts: n/a
|
Re: Structure to Byte Array in VB.NET
><StructLayout(LayoutKind.Explicit)>
>Public Structure TheStruct > <FieldOffset(0)> Dim UpdateMode As Int16 > <FieldOffset(2)> Dim TimeFrameCounter As Int16 > <FieldOffset(4), VBFixedArray(7)> Dim AxisCommandedPosition() As >Integer > <FieldOffset(36), VBFixedArray(7)> Dim AxisEncoderPosition() As >Integer > <FieldOffset(68), VBFixedArray(7)> Dim AxisCommandedVelocity() As >Integer > <FieldOffset(100), VBFixedArray(7)> Dim AxisStatus() As Integer > <FieldOffset(132)> Dim SystemStatus As Integer >End Structure The CLR marshaler doesn't understand the VBFixedArray attribute. Try adding <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)>. >If I have a managed structure of a fixed size explicitly laid out, why >do I have to marshal it through unmanaged memory to use it as a byte >array? Because in the strongly typed world of .NET, you can't treat an object of a certain type (the structure) as an entirely different type (the byte array) even if they happen to share the same memory layout. Mattias -- Mattias Sjögren [C# MVP] mattias @ mvps.org | Please reply only to the newsgroup. |
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|
< Windows Help - MS Office Help - Hardware Support >
| New To Site? | Need Help? |