Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
 Аватар для Artem1990
2 / 2 / 0
Регистрация: 06.01.2013
Сообщений: 114

Ссылка на структуры

13.11.2019, 08:06. Показов 4289. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Сижу разбираюсь с кодом, ни как не могу понять, что тут происходит.
точнее понимаю но воспроизвести не получается.

Есть две структуры вынесенные в заголовочный файл:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
// Заголовок
struct TFTPHeader{
    short opcode;
}__attribute__((packed));
 
 
// Данные
struct TFTPData{
    struct TFTPHeader header;
    short block;
    char data[];
}__attribute__((packed));

и потом принимаем из кода программы Датаграмму через ЮДП сокет:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
void MainWindow::readPendingDatagrams()
{
    if(udpSocketClient->hasPendingDatagrams())
    {
        readbytes = udpSocketClient->readDatagram(recvData, sizeof(recvData), &sender, &senderPort);
 
        struct TFTPHeader *header = (struct TFTPHeader*) recvData; // received data - полученные данные
        struct TFTPData *data = (struct TFTPData*) recvData;
        struct TFTPACK *ack = (struct TFTPACK*) recvData;
        .....
         rFile->write(data->data, readbytes - sizeof(struct TFTPHeader) - sizeof(short));
        }
recvData это массив Char на 1024 элемента:
C++ (Qt)
1
char recvData[1024]
Собственно вопрос: Как понять смысл этого выражения к примеру
struct TFTPData *data = (struct TFTPData*) recvData;

в struct TFTPData имеется ссылка на структуру TFTPHeadr, поле типа short, и массив char, а передаем туда только один массив символов
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.11.2019, 08:06
Ответы с готовыми решениями:

Структуры/Работа с файлами(ошибка линковщика error LNK2019: ссылка на неразрешенный внешний символ)
Задание: Дан файл содержащий сведения о видах журналов редакции.Структура записи файла: -код журнала -название -год выпуска ...

Помещение структуры в вектор, удаление структуры, изменение элементов структуры
Здравствуйте. Помогите разобраться с тем, как: 1 - находить элементы в векторе зная уникальный элемент структуры. 2 - удалять...

Что лучше сквозная ссылка или одна статейная ссылка с одного домена?
Что лучше сквозная ссылка или одна статейная ссылка с одного домена?

33
фрилансер
 Аватар для Алексей1153
6465 / 5679 / 1131
Регистрация: 11.10.2019
Сообщений: 15,122
13.11.2019, 08:56
содержимое начала массива recvData интерпретируется как экземпляр структуры TFTPData , указатель на этот экземпляр - data

ссылок в TFTPData никаких нету. TFTPData::data - это начало массива, лежащего после экземпляра TFTPData (грязный хак, как по мне)
0
 Аватар для Artem1990
2 / 2 / 0
Регистрация: 06.01.2013
Сообщений: 114
13.11.2019, 09:36  [ТС]
Алексей1153, не совсем, что вы имеете ввиду. я понял что в recvData заполняется информация принятая через readDatagram и потом с помощью этих манипуляций присваиваем структуре. Непонятно как информация попадает в data[] структуры TFTPData и почему игнорируется short block;
Цитата Сообщение от Алексей1153 Посмотреть сообщение
ссылок в TFTPData никаких нету
точнее экземпляр структуры. не правильно выразился
C++ (Qt)
1
2
struct TFTPData{
    struct TFTPHeader header;
0
фрилансер
 Аватар для Алексей1153
6465 / 5679 / 1131
Регистрация: 11.10.2019
Сообщений: 15,122
13.11.2019, 09:55
Artem1990, например, входной поток данных имееи такой:

char recvData[1024]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee ,0xff,};

TFTPData* data = (TFTPData*) recvData; //интерпретация начала данных как экземпляра TFTPData, data - указатель на этот экземпляр

поле TFTPData::data место не занимает, потому что определён как массив нулевой длины. Обращение к нему - обращение к данным, лежащим сразу после экземпляра структуры

data->data[0]=0xf8;
data->data[1]=0xf9;

содержимое recvData == {0x11,0x22,0x33,0x44,0xf8,0xf9,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee ,0xff,};

доступ к заголовку
data->header;
0
 Аватар для Artem1990
2 / 2 / 0
Регистрация: 06.01.2013
Сообщений: 114
14.11.2019, 21:41  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
TFTPData::data - это начало массива, лежащего после экземпляра TFTPData (грязный хак, как по мне)
А как бы вы решили бы данную задачу. Просто для примера, и разнообразия. Есть желание учиться, но пока структуры даются, но не так чтобы аххх
0
фрилансер
 Аватар для Алексей1153
6465 / 5679 / 1131
Регистрация: 11.10.2019
Сообщений: 15,122
14.11.2019, 22:13
Artem1990, а задача как поставлена?
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,387
15.11.2019, 00:33
Вообще адрес 1-гo элемента структуры всегда есть адрес и самой структуры.
0
фрилансер
 Аватар для Алексей1153
6465 / 5679 / 1131
Регистрация: 11.10.2019
Сообщений: 15,122
15.11.2019, 08:42
peter_irich, хм, структура s_example с тобой не согласна

C++
1
2
3
4
5
6
7
8
9
10
11
12
struct s_example
{
    int i1=0;
 
    virtual ~s_example()
    {
    }
};
 
s_example e;
void* p1=&e   ;//0x0037f780
void* p2=&e.i1;//0x0037f784
p1!=p2
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,387
15.11.2019, 20:33
Алексей1153, не знаю, что значит "virtual ~s_example(){}", но адреса структуры и её 1-го
элемента должны совпадать, эти свойство C. Сейчас я создал структуру с двумя элементами, 1-й - int,
2-й - double, адрес 1-го совпал с адресом структуры, получал их так же. Поэтому, например, часто
адрес 1-го элемента приводят к адресу на всю структуру, некоторые этим широко пользуются.
0
фрилансер
 Аватар для Алексей1153
6465 / 5679 / 1131
Регистрация: 11.10.2019
Сообщений: 15,122
15.11.2019, 20:41
peter_irich, в Си - да, там нет виртуальных функций. Но тема то в разделе C++
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,387
15.11.2019, 21:27
Алексей1153, Алексей1153, я не думаю, что между C и C++ могут быть различия
на уровне базовых свойств. Значит, в этой структуре i0 не является 1-м элементом. Если я всё же не прав
и в C++ это свойство не гарантируется, то это один из очень редких таких случаев, пишут, что их можно
пересчитать по пальцам одной руки.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
16.11.2019, 12:48
Цитата Сообщение от peter_irich Посмотреть сообщение
Значит, в этой структуре i0 не является 1-м элементом.
Так точно, не является (точнее может не являться). Согласно принятому ABI для С++ в таких случаях первым будет располагаться указатель на таблицу виртуальных функций.
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,387
16.11.2019, 19:59
DrOffset, благодарю. А почему эта таблица должна быть 1-м элементом?
Почему она не может быть, наоборот, последней, ведь компилятору и при исполнении в любом случае
известно, где она? Почему нельзя секцию с ней и с этими функциями нельзя поместить, где угодно?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
16.11.2019, 20:35
Цитата Сообщение от peter_irich Посмотреть сообщение
А почему эта таблица должна быть 1-м элементом?
Просто так договорились. Соглашение такое называется ABI. Например одно из самых распространенных описано тут: https://itanium-cxx-abi.github... tml#vtable

Цитата Сообщение от peter_irich Посмотреть сообщение
Почему она не может быть, наоборот, последней, ведь компилятору и при исполнении в любом случае
известно, где она? Почему нельзя секцию с ней и с этими функциями нельзя поместить, где угодно?
Теоретически да.
Но на практике на эти соглашения может быть завязана не только текущая программа, но и другие, взаимодействующие с ней (например, посредством разделяемых библиотек). И вот тут уже нельзя просто так менять местами такие вещи, потому что остальные программы не узнают об этих изменениях и перестанут работать правильно. В частности под Windows на расположение VPTR в классе завязана вся технология COM. Поэтому обычно такие вещи фиксируются раз и навсегда для конкретной программной платформы и более никогда не меняются. А документы, подобные приведенному выше, призваны обеспечить разработчиков компиляторов единым подходом.
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,387
16.11.2019, 23:02
DrOffset, понятно, если так, то делать нечего, надо соблюдать.
0
 Аватар для Artem1990
2 / 2 / 0
Регистрация: 06.01.2013
Сообщений: 114
17.11.2019, 11:40  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Artem1990, а задача как поставлена?
Задача стоит так, не могу понять вот что:
Приходит ответ на запроса от устройства в таком виде:
Это пример:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
char recvData[64] = {
                    0x00,
                    0x02,
                    0x53,
                    0x45,
                    0x5a,
                    0x5f,
                    0x42,
                    0x4d,
                    0x00,
                    0x53,
                    0x4b,
                    0x59,
                    0x57,
                    0x41,
                    0x4c,
                    0x4c,
                    0x00,
                    0x30,
                    0x31,
                    0x00,
                    0x53,
                    0x4b,
                    0x59,
                    0x57,
                    0x41,
                    0x4c,
                    0x4c,
                    0x2d,
                    0x30,
                    0x31,
                    0x00,
                    0x53,
                    0x45,
                    0x5a,
                    0x00,
                    0x10,
                    0x00};

C++ (Qt)
1
2
3
4
5
6
7
8
void MainWindow::readPendingDatagrams()
{
    if(udpSocketClient->hasPendingDatagrams())
    {
        readbytes = udpSocketClient->readDatagram(recvData, sizeof(recvData), &sender, &senderPort);
 
        struct TFTPHeader *header = (struct TFTPHeader*) recvData; // received data - полученные данные
        struct TFTPData *data = (struct TFTPData*) recvData;
второй элемент массива recvData[64] это Код операции он сохраняется в:
C++ (Qt)
1
struct TFTPHeader *header = (struct TFTPHeader*) recvData;
Начиная с третьего элемента массива идут сами данные, которые помещаются в:
C++ (Qt)
1
struct TFTPData *data = (struct TFTPData*) recvData


Собственно говоря что мне нужно в идеале:
данные пришли в виде предложения начиная '\0' в
C++ (Qt)
1
char recvData[64]
вот этот массив разбить следующим образом:

COD = 0x02

а данные записать в массив.
char words [5];
words[0] = первое слово ;
words[1] = второе слово;
words[2] = третье слово;
words[3] = четвертое слово;
words[4] = пятое слово;

ну или данные сохранить в пять разных переменных можно чар, можно в стринг.

использовал такой код:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
int numberWord =0;
char *words[5] = {0};
 
    char *word = strtok(recvData, " ");
 
    while(word != NULL)
    {
            words[numberWord] = word;
            numberWord++;
            word = strtok(NULL, " ");
    }
собственно говоря и вывод (тестовый код)

C++ (Qt)
1
2
 for (int i = 0; i < numberWord; i++) {
        cout << words[i] << "\n";

Но не срабатывает
0
фрилансер
 Аватар для Алексей1153
6465 / 5679 / 1131
Регистрация: 11.10.2019
Сообщений: 15,122
17.11.2019, 11:56
Artem1990,

так?

0x00, - разделитель
0x02, - код
0x53,0x45,0x5a,0x5f,0x42,0x4d, - слово
0x00, - разделитель
0x53,0x4b,0x59,0x57,0x41,0x4c,0x4c,- слово
0x00, - разделитель
...
0x00, - разделитель
0x10,- слово
0x00 - разделитель
0
 Аватар для Artem1990
2 / 2 / 0
Регистрация: 06.01.2013
Сообщений: 114
17.11.2019, 12:04  [ТС]
Именно так.
только
Цитата Сообщение от Алексей1153 Посмотреть сообщение
0x10
это спец символ которым заканчиваетcя пакет. Он нам не нужен. Просто устройство отправляет в таком виде 0х00, 0x02 .... даннные... 0х00, 0х10
нужен из всего этого пакета только код операции: 0х02 и данные

причем слова могут отличаться по длине. придел пакета 64 байта получается
первое слово 15 символа максимум
второе слово 8 символа максимум
третье 8 символа максимум
четвертое 20 символа максимум
пятое 3 символа максимум
0
 Аватар для Artem1990
2 / 2 / 0
Регистрация: 06.01.2013
Сообщений: 114
17.11.2019, 12:10  [ТС]
Вот что в реальной жизни приходит
только эксперементирую с QByteArray
Миниатюры
Ссылка на структуры  
0
фрилансер
 Аватар для Алексей1153
6465 / 5679 / 1131
Регистрация: 11.10.2019
Сообщений: 15,122
17.11.2019, 13:08
Лучший ответ Сообщение было отмечено Artem1990 как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    const std::vector<uint8_t> recvData{0x00,0x02,0x53,0x45,0x5a,0x5f,0x42,0x4d,0x00,0x53,0x4b,0x59,0x57,0x41,0x4c,0x4c,0x00,0x30,0x31,0x00,0x53,0x4b,0x59,0x57,0x41,0x4c,0x4c,0x2d,0x30,0x31,0x00,0x53,0x45,0x5a,0x00,0x10,0x00};
 
    uint8_t code=0;//тут будет код
    std::vector<std::string> words;//тут будет список слов
    bool ok=false;//флаг - нашли завершалку
 
    do
    {
        auto it_curr=recvData.begin();
        auto it_end=recvData.end();
 
        if(it_curr==it_end)break;
        if(*it_curr!='\0')break;
        it_curr++;
 
        if(it_curr==it_end)break;
        code=*it_curr;
 
        for(it_curr++;it_curr!=it_end;it_curr++)
        {
            //it_curr сейчас указывает на начало очередного слова
 
            //проверка на маркер завершения
            if(*it_curr==0x10)
            {
                ok=true;
                break;
            }
 
            //ищем zero-terminator слова
            auto it_zt=std::find(it_curr,it_end,'\0');
            if(it_zt==it_end)
            {
                //ничего не нашлось. Наверное, это нарушение формата
                break;
            }
 
            //вытаскиваем слово
            const std::string str(it_curr,it_zt);
            words.push_back(str);
 
            //ставим итератор на zt
            it_curr=it_zt;
        }
    }while(0);
по аналогии можно переделать с QByteArray вместо std::vector<uint8_t>
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.11.2019, 13:08
Помогаю со студенческими работами здесь

Как перенести продублировать данные из справочника.ЕдиницыИзмерения.Ссылка в справочник КлассификаторЕдиницИзмерения.Ссылка
Ну вапрос таков есть два справочника 1)КлассификаторЕдиницИзмерения и 2) ЕдиницыИзмерения нужна сделать так что бы у них были индоинтичные...

Если нет файла, но есть ссылка, то будет отображаться ссылка на указанную страницу...
Здравствуйте, понадобилась помощь в php)) В общем есть такой код: &lt;?php $file = get_field('file'); $title = $file; if(...

Как проверить - есть ли обратная ссылка ссылка?
Добрый вечер! Есть сайт. Обменялся год назад с другими сайтами ссылками. Сейчас хочу проверить - у всех ли этих сайтов сохранились...

Загаловок как ссылка - но не ссылка в статье
Как думаете, можно сделать кликабельные загаловки как тут? http://tut.by/ - то есть на главной странице или в любом разделе все загаловки...

Ссылка, гиперссылка и перекрёстная ссылка
Это одно и то же? Кто что думает об этом? В чём разница между ними?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru