Помогите пожалуйста с преобразованием Int2ByteArray
- Войдите на сайт для отправки комментариев
Пт, 13/07/2012 - 08:33
Добрый день, коллеги!
Помогите пожалуйста с функцией преобразования. Очевидно, что я что то не так делаю. Использую ее для того, чтобы послать INT в NetworkClient.write()
Вот функция и пример ее использования
void integerToBytes(ште val, byte b[2]) { b[0] = (byte)((val >> 8) & 0xFF); b[1] = (byte)(val & 0xFF); } // -------------------------------------------- byte packet[4+COUNT]; byte b_act[2]; client.write(b_act, sizeof(int)); byte b_offset[2]; int NR = NUM_OF_REG; client.write(b_offset, sizeof(int));
Посылаю 0 и 2
На клиенте принимаю - получается 0 и вместо 2 - 255.
stream = client.GetStream(); // Read responce from stream BinaryReader bR = new BinaryReader(stream); int act = bR.ReadInt16(); Console.WriteLine("ACT " + act); if (act == 0) { int offset = bR.ReadInt16(); Console.WriteLine("OFFSET " + offset); }
Вроде и там и там 4 байта уходит \ приходит ...
Поправка. как то так.
Да, и когда посылаю просто байты - все работает как часики
а что бы не сделать union
union toobytes {
int val;
byte b_act[2];
};
кода займет меньше
Да, и когда вы шлете
1 byte b_act[]={0x00,0x02};
2 client.write(b_act, 2);
принимете 2 ?
в самой int2bytearray ошибок не вижу.
да, я пробовал и union - думаю что проблема в принимающей стороне. Но вот как понять в чем дело, никак не могу.
Когда я шлю {0x00,0x02} принимаю 512 =)
c BinaryReader не знаком, но интуитивно 512 это 0x200 , меняется порядок байтов, нада просто своп байтов сделать тем же union в клиенте
или физически их перекинуть аналогично int2bytearray
полагаю если пользоваться байтами в union на обоих сторонах одинаково, то не нужно заморачиваться, как они реально лежат в машинном слове.
Покажите код которым принимаете
так второй конец на JAva ? Я решил что две дуины пишут, читают
ну там все что угодно может быть
на яве int 4 байта
ошибки при приеме не дуине или наоборот?
Ну это ECMA script (C#)
там точно 2 байта в инт 16 (это short)
Отправлется из инта 4 байта - Ардуина принимает все отлично. А вот на прием какая то лажа. И большей частью что не нахожу - все передают текст мол "OK" или что то еще, а мне нужно состояние массива в памяти передать и не одного..
Вобщем пока не знаю что делать...
int act = bR.ReadInt16();
Console.WriteLine("ACT " + act);
тут ошибка ?
ну сделайте своп байтов
типа
unsigned int lowbyte,highbyte
highbyte=(act&0xff00)>>8;
lowbyte=act&0x00ff
act=(lowbyte<<8)|highbyte;
act желательно unsigned int
Ну вообщем, как вам правильно подсказал товарищь Borland, "товарищь сержант у вас ручки местами перепутанны". Вначале должен посылатся младший байт, а потом старший. Достаточно в вашем функции из #1 переставить местами строки 2,3
И уже должно заработать. Потом вглядется в них и понять что тут есть лишние &0xFF и привидения типов которые и так неявно происходят. Выкидываем лишние и получаем
Потом опять чухаем маковку и думаем "а нафига нам разбирать на байты если оно уже в памяти в виде байтов лежит? Причем в нужном нам порядке. И выкидываем нафиг фунцию integerToBytes волевым решением
Посылку делаем как-то так (тупо говорим компилятору "вот эту область памяти считай массивом байтов")
В этом случае, если мы вместо NR подставим сразу какой-то массив int-тов (да вообщем-то вообще что угодно) - оно тоже отправится сразу "одним махом". Без необходимости бегать по элементам.
И еще.
>Отправлется из инта 4 байта
Ну что-же вы так не экономно расходуете электричество :) Потом, со стороны ардуины, еще заботся о том что-бы игнорить лишние байты (а значит нельзя тупо в переменную читать, значит опять побайтово возится).
Перейтиде со стороны C# с четерех-байтовых int , на двух байтовые ushort (если знак не нужен) или Int16 (если числа только положительные)
Ну или, если не хочется менять тип переменных, можно тупо закастить перед отправкой ((ushor)data_len)
И, напоследок,
Utils.ConvertInt32ToByteArray тоже смахивает на самописный велосипед. Есть "родной" BitConverter.GetBytes(MySomeValue);
P.S. а кстати, изначально неплохо-бы было дать ссылки на библиотеки ардуины которую вы юзаете для коммуникации. А то о функциях которые "есть в наличии" и какие у них типа параметров - можно только гадать.
Вот спасибо, как всегда меня выручаете =) Волевым решением, выкидываю.
Сейчас я юзаю Int16 для передачи. Там вобще и byte мог бы сойти
Utils.ConvertInt32ToByteArray - это оно и есть, просто для удобство в утилсы запихнул.
М.. ну только эти.. больше ничего
#include <SPI.h>
#include <Ethernet.h>
#include <MsTimer2.h>
>Сейчас я юзаю Int16 для передачи. Там вобще и byte мог бы сойти
Ну если байт, так пусть и будет байт. Тогда вообще можно будет послать нафиг все эти конвертеры. Должен быть сдоровый минимализм-обленизм.
>Utils.ConvertInt32ToByteArray - это оно и есть, просто для удобство в утилсы запихнул.
Ну это же "осталось за кадром". Кстати, если воспользоватся Extention методами (дабавить слово this перед Int32 I32 ) и переименовать методов в просто ToByteArray(), то можно будет "конверсию" вызвать еще компактней data_len.ToByteArray();
>М.. ну только эти.. больше ничего
Ну вот Ethernet.h имелся ввиду. Что это за либа? (их столько имеется под этим именем :) Где ее брали. Ну вообще-то не очень важно, просто иногда такая инфа облегчает задачу дать полее корректный совет. И, со стороны C#, просто любопытно, объект client он какого типа?