2015-11-13 7 views
0

У меня есть серверное приложение, написанное на C, которое должно отправить скриншот throguh socket и C# gui client. Проблема в том, что я не могу преобразовать массив байтов в структуру из-за исключения. Простое задание массива char для struct в C/C++, но не так просто в C#. Вот тестовый код:Исключение при преобразовании байтового массива в структуру

public partial class Form1 : Form 
    { 
     const int magic = 101; 
     enum command {GET_SCREEN = 1, MOVE_MOUSE, CLICK_MOUSE }; 

     public struct send_packet 
     { 
      public int magic; 
      public int cmd; 

     }; 

     public struct recv_packet 
     { 
      public int magic; 
      public int code; 
      public int length; 
      public byte[] body; 

     }; 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      int port = 4000; 
      TcpClient client = new TcpClient("127.0.0.1", 4000); 
      NetworkStream nws = client.GetStream(); 
      BinaryWriter bw = new BinaryWriter(nws); 
      BinaryReader br = new BinaryReader(nws); 
      byte[] buff = new byte[512]; 

      send_packet pkt = new send_packet(); 
      pkt.magic = magic; 
      pkt.cmd = (int)command.GET_SCREEN; 
      while (true) 
      { 

       bw.Write(pkt.magic); 
       bw.Write(pkt.cmd); 

       br.Read(buff, 0, 512); 
       GCHandle pinnedPacket = GCHandle.Alloc(buff, GCHandleType.Pinned); 
       recv_packet rcv_pkt = (recv_packet)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(recv_packet)); 
       //string str = System.Text.Encoding.Default.GetString(rcv_pkt.length); 
       string str = rcv_pkt.length.ToString(); 
       MessageBox.Show(str); 


      } 

     } 
    } 

Что это может быть? Текст исключения на русском языке, но есть самая важная информация: «System.AccessViolationException» в mscorlib.dll, попытка чтения или записи в защищенную память. Что-то вроде того. Это происходит прямо в этой строке recv_packet rcv_pkt = (recv_packet)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(recv_packet));

Здесь я получил объяснение, почему это не работает и своего рода решения https://social.msdn.microsoft.com/Forums/vstudio/en-US/3c152957-91e7-43bf-91de-a047a3d124f5/exception-when-converting-byte-array-to-structure?forum=csharpgeneral

+2

Что такое excep и точно, когда это произойдет? – Culme

+0

Я только что обновил сообщение с этой информацией. –

+0

Таким образом, это может быть проще .. http://stackoverflow.com/a/21510978/932418 – Eser

ответ

-1
//Functions to turn byte arrays to structs. 

    public static byte[] RawSerialize<T>(T frqStruct) 
    where T : struct 
    { 
     int rawsize = Marshal.SizeOf<T>(); 

     IntPtr i = IntPtr.Zero; 
     try 
     { 
      i = Marshal.AllocHGlobal(rawsize); 
      Marshal.StructureToPtr<T>(frqStruct, i, false); 
      byte[] rawdatas = new byte[rawsize]; 
      Marshal.Copy(i, rawdatas, 0, rawsize); 
      return rawdatas; 
     } 
     finally 
     { 
      if (i != IntPtr.Zero) 
      { 
       Marshal.FreeHGlobal(i); 
      } 
     } 
    } 

    public static T RawDeserialize<T>(byte[] bytearray) 
    where T : struct 
    { 
     int len = Marshal.SizeOf<T>(); 

     IntPtr i = IntPtr.Zero; 
     try 
     { 
      i = Marshal.AllocHGlobal(len); 

      Marshal.Copy(bytearray, 0, i, len); 

      return Marshal.PtrToStructure<T>(i); 
     } 
     finally 
     { 
      if (i != IntPtr.Zero) 
      { 
       Marshal.FreeHGlobal(i); 
      } 
     } 
    } 

использовать как этот

Struct struct1=new Struct(); 
byte[] outarr = RawSerialize(struct1); 

struct1 = RawDeserialize<Struct>(outarr); 

Также убедитесь, ваши структуры объявлены правильно (с размерами и т. д.):

[StructLayout(LayoutKind.Sequential, Size = 24)] 
public struct myStruct 
{ 
    public byte byte1; 
    public byte byte2; 
    public ushort reserved; 
    //Was char[16] 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
    public string name; // null terminated 

    public uint version; 
} 
+0

Хочет попробовать, но получил сообщения об ошибках, что Sizeof и PtrToStructure не могут использоваться с аргументами типа –

+0

@ АлександрПушкин Обновлено –

+0

все еще есть аранжировщик –

Смежные вопросы