C# stuct --> byte[] probléma

C# stuct --> byte[] probléma
2018-11-17T22:04:18+01:00
2018-11-18T21:46:28+01:00
2022-10-15T21:35:56+02:00
RortHer
Sziasztok!

Kis segítséget szeretnék kérni, már egy ideje küzdök vele, de nem sikerül :(

[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct card { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] cardID; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] DateTime; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] DoorID; }; public card[] cards = new card[180]; public byte[] data = new byte[800]; private void button1_Click(object sender, EventArgs e) { string id = "00001"; string dt = "2018"; string did = "0255"; cards[0].cardID = Encoding.ASCII.GetBytes(id); // 5 hosszú cards[0].DateTime = Encoding.ASCII.GetBytes(dt); // 4 hosszú cards[0].DoorID = Encoding.ASCII.GetBytes(did); // 4 hosszú id = "00002"; dt = "2018"; did = "0255"; cards[1].cardID = Encoding.ASCII.GetBytes(id); cards[1].DateTime = Encoding.ASCII.GetBytes(dt); cards[1].DoorID = Encoding.ASCII.GetBytes(did); Array.Copy(cards, 0, data, 2, 2); //ez nem működik }
A data byte tömbbe szeretném a cards struktúra egy részét bemásolni,
a data majd tovább lesz küldve mikrovezérlő felé.

A data tömb eleje fejléc lesz.
A cards struktúrát adatbázisból töltöm majd.

Nagyon szépen köszönöm a segítséget!

üdv!
Mutasd a teljes hozzászólást!

  • Ezek alapján:
    Structure to ByteArray Extension
    Best way to combine two or more byte arrays in C#

    Valami ilyesmi:

    int cardDataSize = Marshal.SizeOf(cards[0]); // 13 hosszú for (var i = 0; i < 2; i++) { IntPtr handle = Marshal.AllocHGlobal(cardDataSize); Marshal.StructureToPtr(cards, handle, true); Marshal.Copy(handle, data, i * cardDataSize, cardDataSize); }
    Mutasd a teljes hozzászólást!
  • Vakarom a buksit azon a lehetőségen, hogy egy nem is létező problémát akarsz megoldani. A kulcs-kérdés: konkrétan hogyan kommunikálnál a mikrovezérlővel?
    Mutasd a teljes hozzászólást!
  • Szia,

    köszönöm, hogy foglalkoztál vele!
    Az alábbi sor hibát adott:

    Marshal.StructureToPtr(cards, handle, true);

    Hiba:
    The specified structure must be blittable or have layout information.

    Keresgéltem tovább és az alábbi átalakítással sikerült megoldani, hogy legalább
    tömbbe tegyem a struktúrát:

    [StructLayout(LayoutKind.Explicit)] public struct card { [FieldOffset(0)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] cardID; [FieldOffset(8)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] DateTime; [FieldOffset(16)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] DoorID; } public static byte[] StructureToByteArray(card[] array) { int structSize = Marshal.SizeOf(typeof(card)); int size = array.Length * structSize; byte[] arr = new byte[size]; IntPtr ptr = Marshal.AllocHGlobal(size); for (int i = 0; i < array.Length; i++) Marshal.StructureToPtr(array
    , ptr + i * structSize, true); Marshal.Copy(ptr, arr, 0, size); Marshal.FreeHGlobal(ptr); return arr; } private void button1_Click(object sender, EventArgs e) { card[] cards = new card[200]; string id = "00001"; string dt = "2018"; string did = "0255"; cards[0].cardID = Encoding.ASCII.GetBytes(id); // 5 hosszú cards[0].DateTime = Encoding.ASCII.GetBytes(dt); // 4 hosszú cards[0].DoorID = Encoding.ASCII.GetBytes(did); // 4 hosszú id = "00002"; dt = "2018"; did = "0255"; cards[1].cardID = Encoding.ASCII.GetBytes(id); // 5 hosszú cards[1].DateTime = Encoding.ASCII.GetBytes(dt); // 4 hosszú cards[1].DoorID = Encoding.ASCII.GetBytes(did); // 4 hosszú byte[] teszt = StructureToByteArray(cards); }
    a teszt tömbbe végül belekerülnek az adatok, ezt már tudom tovább használni.

    Köszönöm!

    Mutasd a teljes hozzászólást!
  • Szia,

    Neked is köszönöm, hogy időt szántál rá!

    Adatbázisból lekérdezéssel az adatokat az említett struktúrába teszem.
    Ezt követően összeállítok egy olyan tömböt, amit már tudok a controller felé
    küldeni Etherneten (wiz820io).
    A kommunikáció rendben működik, az utolsó lépés hogy a byte tömböket megfelelő
    formába hozzam.
    Kitaláltam rá egy protokollt.

    data[0] <-- funkció kód
    data[1-4] <-- dátum lesz unix formában
    stb

    Köszönöm!
    Mutasd a teljes hozzászólást!
  • Akkor még mindig vakarom a buksit. Minek az unmanaged erőlködés? Net socketon kiküldeni valamit kb ennyi:

    public static System.Net.Sockets.UdpClient udp_handle; System.Int32 server_port; udp_handle= new System.Net.Sockets.UdpClient(server_port); System.String dest_ip_addr; System.Int32 dest_port; System.String pkt_msg; System.Byte[] pkt_bytes= System.Text.Encoding.ASCII.GetBytes(pkt_msg); udp_handle.Send(pkt_bytes, pkt_bytes.Length, dest_ip_addr, dest_port);
    Használhatsz normál byte tömböt is, amibe legrosszabb esetben egyesével rakod bele a byte-okat pozíció helyesen.
    Mutasd a teljes hozzászólást!
  • Szia,

    végül átalakítottam, talán nem olyan szép de így működik jól:

    private void cards_to_data(card[] array, byte[] data, int start, int len, int data_offs) { if (len <= 60) // a data tömb nem lehet nagyobb mint 800 (60*13+5 = 785) ezért max 60 kártyszámot lehet átküldeni egyszerre { for (int i = 0; i < len; i++) { Array.Copy(array[start].cardID, 0, data, data_offs + i * 13, 5); Array.Copy(array[start].DateTime, 0, data, data_offs + i * 13 + 5, 4); Array.Copy(array[start].DoorID, 0, data, data_offs + i * 13 + 9, 4); } } }
    simán csak összerakom a kívánt tömböt. Van benne offset, így befér elé a tejléc is.

    A küldés pedig:

    private void kuld(byte[] out_data, int len) { string ip = System.Configuration.ConfigurationManager.AppSettings["kozpontok_1_ip"]; int port = Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["kozpontok_1_port"]); try { TcpClient client = new TcpClient(ip, port); NetworkStream networkStream = client.GetStream(); StreamWriter writer = new StreamWriter(client.GetStream()); byte[] bytes = new byte[29]; networkStream.ReadTimeout = 10; networkStream.Write(out_data, 0, len); networkStream.Read(bytes, 0, 29); string data = Encoding.UTF8.GetString(bytes); tbox.Text += ("Server sent message: {0}" + ByteArrayToString(bytes)) + "\r\n"; ; networkStream.Close(); writer.Close(); client.Close(); } catch (Exception) { tbox.Text += "küldési hiba"; } }

    üdv!
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd