Стартовая страница › Форумы › Разработка и интеграция › Не работает код в драйвере (ахинея какая то)
- В этой теме 12 ответов, 3 участника, последнее обновление 4 года, 8 месяцев назад сделано Mikhail.
-
АвторСообщения
-
17.07.2019 в 14:59 #12827manjey73Участник
Использую список для массива байт в KpLogic
объявлен
private List<byte[]> listInBuf = new List<byte[]>();в запросах сессии, где код
private void Request — в котором запросы и ответы согласно количеству в настройках Коммуникатора при ошибке
while (RequestNeeded(ref tryNum))
{
Внутри есть еще мой while такого вида
Если количество страниц больше 1, то выполняется while
int cp = 0;
int startIn = 0; // стартовый индекс первой страницы
listInBuf.Clear(); // Очистка списка при очередном чтении
while (cp < colPage) // colPage это количество страниц которые я запрашиваю
{
Array.Copy(inBuf, startIn, InBuf, 0, InBuf.Length); // копирую в буфер часть принятых байт (собственно одну страницу, к примеру принимаю две
listInBuf.Add(InBuf); // добавляю в список массив одной страницы
// TEST TEST TEST
string df = ScadaUtils.BytesToHex(listInBuf[cp]); // выводит два правильных буфера
ExecWriteToLog(df);
// Вот когда здесь сделать вывод и какие то действия то буферы отличаются с 0 и 1 индексами — переменная cp
startIn = startIn + InBuf.Length;
cp++;
}
}
Далее мы выходим из этого void и возвращаемся куда то в программе.
Если сделать ExecWriteToLog(«Размер списка — » + listInBuf.Count); — то получим честный и правильный ответ = 2 (мы же прочли 2 страницы, все четко)
НО далее чудеса,
for (int o = 0; o < listInBuf.Count; o++)
{
string gg = ScadaUtils.BytesToHex(listInBuf[o]);
ExecWriteToLog(gg);
} // должно напечатать два РАЗНЫХ массива но сволочь по обоим индексам массив последней страницы ??????????Уже голову сломал почему ? Почему внутри моего while после Add это разные массивы, а после того как выйду, список сохранен, не обнулен, но массивы по обоим индексам одинаковы ?
Пробовал и с Dictionary это проделать и выводить через foreach результат всегда одинаковый…Могу прислать код чтобы глянули именно текст, потому что это dll и без доступа к прибору будут ошибки…
- Эта тема была изменена 4 года, 8 месяцев назад от manjey73.
17.07.2019 в 15:12 #12829manjey73УчастникАдрес- Ключ- Номер стр.- IndGr- IndObj 1072 - 45 - 16 - 0 - 0 16970 - 45 - 265 - 0 - 2 16978 - 45 - 265 - 0 - 3 16986 - 45 - 265 - 0 - 1 17018 - 45 - 265 - 0 - 4 48 1 - 1 Номер страницы - 16 Количество страниц - 1 Количество переменных - 1 26 10 18 58 2 - 4 Номер страницы - 265 Количество страниц - 2 Количество переменных - 4 Количество запросов Flash - 2 2019-07-17 15:05:05 Запуск линии связи 21 "Логика_RS" 2019-07-17 15:05:05 Установка TCP-соединения с 185.44.8.247:4000 2019-07-17 15:05:06 Сеанс связи с КП 130 "Логика СПТ941_11", тип: KpLogika, адрес: 5 Отправка (16): FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF Запрос версии ПО Отправка (9): 10 05 3F 00 00 00 00 BB 16 Приём (8/8): 10 05 3F 92 29 02 FE 16 OK! Отправка (9): 10 05 45 10 00 01 00 A4 16 Приём (69/69): 10 05 45 00 FF FF FF 30 20 20 20 20 20 20 20 00 00 00 00 00 FF FF FF 30 20 20 20 20 20 20 20 00 00 00 00 00 FF FF FF 30 20 20 20 20 20 20 20 00 00 00 00 00 FF FF FF 30 35 20 20 20 20 20 20 05 00 00 00 67 16 OK! Размер списка - 0 Отправка (9): 10 05 45 09 01 02 00 A9 16 Приём (138/138): 10 05 45 00 00 00 00 00 00 00 00 00 00 84 B4 00 00 29 5C 4F 7E 1F B4 00 00 C0 EC 2E 7E 00 00 00 00 00 00 00 00 FB B1 00 00 C8 7B 15 7B FB B1 00 00 C8 7B 15 7B 00 00 00 00 00 00 00 00 DA 00 00 00 9B FE 8F 16 10 05 45 7C 7D 8A 5A 00 00 75 CD 0C 7E 00 00 00 00 00 00 00 00 01 00 00 00 13 07 10 17 A5 00 7B 02 93 02 13 03 1F 17 17 00 1D 00 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3B 16 Приём (69): 10 05 45 00 00 00 00 00 00 00 00 00 00 84 B4 00 00 29 5C 4F 7E 1F B4 00 00 C0 EC 2E 7E 00 00 00 00 00 00 00 00 FB B1 00 00 C8 7B 15 7B FB B1 00 00 C8 7B 15 7B 00 00 00 00 00 00 00 00 DA 00 00 00 9B FE 8F 16 1005450000000000000000000084B40000295C4F7E1FB40000C0EC2E7E0000000000000000FBB10000C87B157BFBB10000C87B157B0000000000000000DA0000009BFE8F16 1005450000000000000000000084B40000295C4F7E1FB40000C0EC2E7E0000000000000000FBB10000C87B157BFBB10000C87B157B0000000000000000DA0000009BFE8F16 OK! 0 1005450000000000000000000084B40000295C4F7E1FB40000C0EC2E7E0000000000000000FBB10000C87B157BFBB10000C87B157B0000000000000000DA0000009BFE8F16 69 Приём (69): 10 05 45 7C 7D 8A 5A 00 00 75 CD 0C 7E 00 00 00 00 00 00 00 00 01 00 00 00 13 07 10 17 A5 00 7B 02 93 02 13 03 1F 17 17 00 1D 00 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3B 16 1005457C7D8A5A000075CD0C7E00000000000000000100000013071017A5007B02930213031F1717001D005800000000000000000000000000000000000000000000003B16 1005457C7D8A5A000075CD0C7E00000000000000000100000013071017A5007B02930213031F1717001D005800000000000000000000000000000000000000000000003B16 OK! 1 1005457C7D8A5A000075CD0C7E00000000000000000100000013071017A5007B02930213031F1717001D005800000000000000000000000000000000000000000000003B16 138 0000000000000000000084B40000295C4F7E1FB40000C0EC2E7E0000000000000000FBB10000C87B157BFBB10000C87B157B0000000000000000DA0000009BFE7C7D8A5A000075CD0C7E00000000000000000100000013071017A5007B02930213031F1717001D0058000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 Размер списка - 2 1005457C7D8A5A000075CD0C7E00000000000000000100000013071017A5007B02930213031F1717001D005800000000000000000000000000000000000000000000003B16 1005457C7D8A5A000075CD0C7E00000000000000000100000013071017A5007B02930213031F1717001D005800000000000000000000000000000000000000000000003B16 1 - 26 2 - 10 3 - 18 4 - 58
Вот такая вот забава. Там, где буферы отличаются, это вывод в лог внутри моего while. А после «Размер списка — 2» это вывод списка уже после выхода из void Request… Вот такая вот засада и как она происходит непонятно…
17.07.2019 в 17:13 #12836MikhailМодераторArray.Copy(inBuf, startIn, InBuf, 0, InBuf.Length);
А что за переменные inBuf и InBuf, где они объявляются и где присваиваются?
listInBuf.Add(InBuf); — наверное InBuf это один и тот же массив на каждой итерации цикла.
17.07.2019 в 17:55 #12838manjey73УчастникinBuf — это входной буфер из прибора, полный на две страницы
InBuf — в этот буфер я копирую одну страницу из двух и заношу в List.
Вот пока я нахожусь внутри кода while и тут же обрабатываю байтовый буфер из списка то в нем правильный массив, то есть в 0 индекс списка попадает первая половина общего буфера, в 1 индекс списка попадает вторая половина списка, все хорошо.
Но стоит завершиться коду void и вернуться для дальнейшей обработке по обоим индексам списка оказывается вторая половина общего буфера. То же самое происходит и со Словарем. Пока внутри кода while массивы разные, при выходе одинаковые.listInBuf.Add(InBuf) — в том то и дело, если тут же вывести listInBuf[0] то это будет первая половина общего массива. Но дальше по коду, после выхода оказывается не так.
Вот это и смущает почему ???- Этот ответ был изменен 4 года, 8 месяцев назад от manjey73.
18.07.2019 в 07:36 #12842KazamУчастникУх ты! Еще кто-то СПТ мучает =))) сорри за офтоп
18.07.2019 в 10:57 #12843manjey73УчастникДа драйвер пишу, убил бы таких разработчиков. Надо же додуматься не сделать выравнивая переменных по размеру страницы, начало переменной в одной странице, окончание на следующей.
И еще момент, первый раз такое вижу, при чтении 2 и более страниц будет
заголовок * количество страниц, Контрольная сумма * на количество страниц и завершающий код * на количество страниц в пакете.
То есть сделать один заголовок, одну контрольную сумму и одно окончание пакета не додумались…
Я уже не говорю про свое представление double, float и так далее. Тут Михаилу спасибо за готовый код, сам бы я долго соображал как это преобразовывать.
Ну еще там хватает приколов с адресацией переменных…18.07.2019 в 11:16 #12844manjey73УчастникВ продолжении темы.
// TEST TEST TEST ExecWriteToLog("Буфер из списка listInBuf[cp]"); string df = ScadaUtils.BytesToHex(listInBuf[cp]); // выводит два правильных буфера ExecWriteToLog(df + "\n"); ExecWriteToLog("Буфер из listInBuf[0]"); string ds = ScadaUtils.BytesToHex(listInBuf[0]); // выводит два НЕПРАВИЛЬНЫХ буфера ExecWriteToLog(ds); //// TEST TEST TEST
Это тестовый код внутри while
А вот вывод в логеБуфер из списка listInBuf[cp] 1005450000000000000000000084B40000295C4F7E1FB40000C0EC2E7E0000000000000000FBB10000C87B157BFBB10000C87B157B0000000000000000DA0000009BFE8F16 Буфер из listInBuf[0] 1005450000000000000000000084B40000295C4F7E1FB40000C0EC2E7E0000000000000000FBB10000C87B157BFBB10000C87B157B0000000000000000DA0000009BFE8F16 OK! Приём (69): 10 05 45 7C 7D 9E 5A 00 00 75 CD 0C 7E 00 00 00 00 00 00 00 00 01 00 00 00 13 07 11 17 A6 00 93 02 AB 02 13 03 1F 17 17 00 1D 00 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F5 16 Буфер из списка listInBuf[cp] 1005457C7D9E5A000075CD0C7E00000000000000000100000013071117A6009302AB0213031F1717001D00580000000000000000000000000000000000000000000000F516 Буфер из listInBuf[0] 1005457C7D9E5A000075CD0C7E00000000000000000100000013071117A6009302AB0213031F1717001D00580000000000000000000000000000000000000000000000F516 OK!
Чудеса, как на второй итерации while в 0-м индексе оказался второй кусок буфера ?
18.07.2019 в 13:37 #12846manjey73УчастникПобедил я эту тему но не понимаю смысла…
Вверху было объявление private byte[] inBuf1 = new byte[69];
Внутри моего цикла while было
Array.Copy(inBuf, startIn, inBuf1, 0, inBuf1.Length);
listInBuf.Add(inBuf1);то есть копирование в буфер одной страницы из общего буфера и добавления его в список
И на второй итерации в 0 регистре списка оказывался второй буфер
Внутри while цикла перед Array.Copy прописалbyte[] inBuf1 = new byte[69]; // удалил его объявление вверху
И о чудо в 0 регистре списка сохраняется первый кусок.
Непонятно, буфер объявлен, перед занесением в список происходит копирование, то есть буфер обновляется новыми данными, как в списке по 0 регистру в первом варианте оказываются данные второго буфера ?????? Ведь логика по сути та же…
18.07.2019 в 17:29 #12848MikhailМодераторВ начале было listInBuf.Add(InBuf) — то есть в список добавлялся всё время один и тот же буфер. Массив — это ссылочный тип, поэтому в список добавлялась просто одна и та же ссылка.
18.07.2019 в 17:54 #12853manjey73УчастникДа это я уже переименовал, на всякий случай, немного подчищая. В обоих случаях InBuf и inBuf1 были равны 69 байт и прежде чем попасть в Add списка было копирование.
Так вот если объявить массив вверху как private и т.д. такое и происходит.
Опять же, выше писал, то же самое происходит, если я это делал через Словарь int, byte[], где в качестве ключа был индекс страницы. Та же картина…Тут хоть тресни в чем-то другом дело…
Может это какой-то глюк C# ?19.07.2019 в 17:42 #12882MikhailМодераторКопирования недостаточно. Надо именно создавать новый массив с помощью new
Может это какой-то глюк C# ?
Вероятность этого близка к 0 в данной ситуации.
19.07.2019 в 22:27 #12884manjey73УчастникСтранно, почему недостаточно. Был массив — в него скопировали данные, записали в список, опять скопировали данные и занесли в список. В списке получается что, не копии этих буферов с разными данными а ссылка на один буфер ?. Если так, то вероятно так и есть. В цикле помогло new byte[]
20.07.2019 в 14:12 #12886MikhailМодераторВ списке получается что, не копии этих буферов с разными данными а ссылка на один буфер ?
Да, именно так.
-
АвторСообщения
- Вы должны авторизироваться для ответа в этой теме.