Не работает код в драйвере (ахинея какая то)

Стартовая страница Форумы Разработка и интеграция Не работает код в драйвере (ахинея какая то)

В этой теме 12 ответов, 3 участника, последнее обновление Mikhail Mikhail 1 месяц назад.

Просмотр 13 сообщений - с 1 по 13 (из 13 всего)
  • Автор
    Сообщения
  • #12827
    Аватар
    manjey73
    Участник

    Использую список для массива байт в 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 и без доступа к прибору будут ошибки…

    • Тема изменена 1 месяц назад пользователем Аватар manjey73.
    #12829
    Аватар
    manjey73
    Участник
    Адрес- Ключ- Номер стр.- 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… Вот такая вот засада и как она происходит непонятно…

    #12836
    Mikhail
    Mikhail
    Модератор

    Array.Copy(inBuf, startIn, InBuf, 0, InBuf.Length);

    А что за переменные inBuf и InBuf, где они объявляются и где присваиваются?

    listInBuf.Add(InBuf); — наверное InBuf это один и тот же массив на каждой итерации цикла.

    #12838
    Аватар
    manjey73
    Участник

    inBuf — это входной буфер из прибора, полный на две страницы
    InBuf — в этот буфер я копирую одну страницу из двух и заношу в List.
    Вот пока я нахожусь внутри кода while и тут же обрабатываю байтовый буфер из списка то в нем правильный массив, то есть в 0 индекс списка попадает первая половина общего буфера, в 1 индекс списка попадает вторая половина списка, все хорошо.
    Но стоит завершиться коду void и вернуться для дальнейшей обработке по обоим индексам списка оказывается вторая половина общего буфера. То же самое происходит и со Словарем. Пока внутри кода while массивы разные, при выходе одинаковые.

    listInBuf.Add(InBuf) — в том то и дело, если тут же вывести listInBuf[0] то это будет первая половина общего массива. Но дальше по коду, после выхода оказывается не так.
    Вот это и смущает почему ???

    • Ответ изменён 1 месяц назад пользователем Аватар manjey73.
    #12842
    Аватар
    Kazam
    Участник

    Ух ты! Еще кто-то СПТ мучает =))) сорри за офтоп

    #12843
    Аватар
    manjey73
    Участник

    Да драйвер пишу, убил бы таких разработчиков. Надо же додуматься не сделать выравнивая переменных по размеру страницы, начало переменной в одной странице, окончание на следующей.
    И еще момент, первый раз такое вижу, при чтении 2 и более страниц будет
    заголовок * количество страниц, Контрольная сумма * на количество страниц и завершающий код * на количество страниц в пакете.
    То есть сделать один заголовок, одну контрольную сумму и одно окончание пакета не додумались…
    Я уже не говорю про свое представление double, float и так далее. Тут Михаилу спасибо за готовый код, сам бы я долго соображал как это преобразовывать.
    Ну еще там хватает приколов с адресацией переменных…

    #12844
    Аватар
    manjey73
    Участник

    В продолжении темы.

                                // 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-м индексе оказался второй кусок буфера ?

    #12846
    Аватар
    manjey73
    Участник

    Победил я эту тему но не понимаю смысла…
    Вверху было объявление 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 регистру в первом варианте оказываются данные второго буфера ?????? Ведь логика по сути та же…

    #12848
    Mikhail
    Mikhail
    Модератор

    В начале было listInBuf.Add(InBuf) — то есть в список добавлялся всё время один и тот же буфер. Массив — это ссылочный тип, поэтому в список добавлялась просто одна и та же ссылка.

    #12853
    Аватар
    manjey73
    Участник

    Да это я уже переименовал, на всякий случай, немного подчищая. В обоих случаях InBuf и inBuf1 были равны 69 байт и прежде чем попасть в Add списка было копирование.

    Так вот если объявить массив вверху как private и т.д. такое и происходит.
    Опять же, выше писал, то же самое происходит, если я это делал через Словарь int, byte[], где в качестве ключа был индекс страницы. Та же картина…

    Тут хоть тресни в чем-то другом дело…
    Может это какой-то глюк C# ?

    #12882
    Mikhail
    Mikhail
    Модератор

    Копирования недостаточно. Надо именно создавать новый массив с помощью new

    Может это какой-то глюк C# ?

    Вероятность этого близка к 0 в данной ситуации.

    #12884
    Аватар
    manjey73
    Участник

    Странно, почему недостаточно. Был массив — в него скопировали данные, записали в список, опять скопировали данные и занесли в список. В списке получается что, не копии этих буферов с разными данными а ссылка на один буфер ?. Если так, то вероятно так и есть. В цикле помогло new byte[]

    #12886
    Mikhail
    Mikhail
    Модератор

    В списке получается что, не копии этих буферов с разными данными а ссылка на один буфер ?

    Да, именно так.

Просмотр 13 сообщений - с 1 по 13 (из 13 всего)

Для ответа в этой теме необходимо авторизоваться.