I'm trying to convert the content of a byte[]
read from a named pipe to a managed c# struct. The over the wire data is a series of 3 UInt32
followed by a null
terminated double byte string.
Following many examples that I have seen online, I'm copying the content of the byte buffer to unmanaged memory, before using Marshal.PtrToStructure()
to turn or cast the unmanaged memory pointer into a managed object. The call to Marshal.PtrToStructure()
yields the following error:
Managed Debugging Assistant 'FatalExecutionEngineError' Message=Managed Debugging Assistant 'FatalExecutionEngineError' : 'The runtime has encountered a fatal error. The address of the error was at 0x7444c38a, on thread 0x25a4. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.'
I've created a simple example that demonstrate the error:
using System;
using System.Runtime.InteropServices;
namespace MarshalingTest
{
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
public struct CommandStruct
{
/* Message Header */
public UInt32 signature;
public UInt32 payloadSize;
public UInt32 commandType;
/* Payload */
[MarshalAs(UnmanagedType.LPWStr)]
public string payload;
}
class Program
{
private static byte[] RawData = new byte[] { 0x56, 0x50, 0x46, 0x47, // 4 bytes Message Signature
0x0A, 0x00, 0x00, 0x00, // 4 bytes Payload Size
0x40, 0x00, 0x00, 0x00, // 4 bytes Command Type
// Null Terminated double byte string "Wall"
0x57, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00
};
static void Main(string[] args)
{
// Allocate unmanaged memory and copy the content of the RawData buffer to it
int size = RawData.Length;
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(RawData, 0, ptr, size);
//Copy unmanaged object to managed object
CommandStruct obj = (CommandStruct)Marshal.PtrToStructure(ptr, typeof(CommandStruct));
// Free the unmanaged memory
Marshal.FreeHGlobal(ptr);
Console.WriteLine("Signature: {0}", obj.signature);
Console.WriteLine("Payload size: {0}", obj.payloadSize);
Console.WriteLine("Command Type: {0}", obj.commandType);
Console.WriteLine("Payload: {0}", obj.payload);
}
}
}
I've at a loss with this one. I've spent the past couple of days researching the issue and trying out different variations of the same code with no luck. I'll be grateful for any help I can get.
Thank you in advance,
T.
User contributions licensed under CC BY-SA 3.0