Russian Qt Forum
Сентябрь 30, 2024, 22:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: двухбайтное число в quint16  (Прочитано 12515 раз)
Edynchik
Гость
« : Февраль 10, 2015, 21:21 »

Есть такая ситуация, число лежит в массиве побайтно младшими вперед например 0x020e, т.е.
Код:
buf[0] = 0x0e;buf[1] =0x02;
как сделать так, чтобы записать число в quint16? пробовал
Код:
quint16 n = (quint16)buf[1];
,чтобы явное преобразование захватило сразу два байта, но что то не выходит, прошу помощи.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Февраль 10, 2015, 21:23 »

Есть такая ситуация, число лежит в массиве побайтно младшими вперед например 0x020e, т.е.
Код:
buf[0] = 0x0e;buf[1] =0x02;
как сделать так, чтобы записать число в quint16? пробовал
Код:
quint16 n = (quint16)buf[1];
,чтобы явное преобразование захватило сразу два байта, но что то не выходит, прошу помощи.
buf[0]
Записан
Edynchik
Гость
« Ответ #2 : Февраль 10, 2015, 21:24 »

да и buf[0] пробовал выдает не 2 а 14, что то тоже не то, там вроде указатель должен быть???
« Последнее редактирование: Февраль 10, 2015, 21:35 от Edynchik » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4744



Просмотр профиля WWW
« Ответ #3 : Февраль 10, 2015, 21:35 »

наверное что-то типа такого должно быть:
Код
C++ (Qt)
quint16 n = *(reinterpret_cast<quint16 *>(buf));
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Edynchik
Гость
« Ответ #4 : Февраль 10, 2015, 21:51 »

спасибо, правда сейчас нет под рукой компилятора, завтра проверю.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #5 : Февраль 10, 2015, 22:19 »

qFromLittleEndian, qFromBigEndian.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #6 : Февраль 11, 2015, 12:55 »

наверное что-то типа такого должно быть:
Код
C++ (Qt)
quint16 n = *(reinterpret_cast<quint16 *>(buf));
будет работать до поры до времени, пока адрес buf выровнен. если не проследить за выравниванием, то словите ошибку во время выполнения, причем трудноуловимую. лучше не баловаться подобным приведением типа, а сделать что-то типа

quint16 n = buf[0] + (buf[1] >> Крутой;
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Февраль 11, 2015, 13:23 »

наверное что-то типа такого должно быть:
Код
C++ (Qt)
quint16 n = *(reinterpret_cast<quint16 *>(buf));
будет работать до поры до времени, пока адрес buf выровнен. если не проследить за выравниванием, то словите ошибку во время выполнения, причем трудноуловимую. лучше не баловаться подобным приведением типа, а сделать что-то типа

quint16 n = buf[0] + (buf[1] >> Крутой;
Что за мифическое выравнивание? Давайте проверим
Код
C++ (Qt)
#pragma pack(push, 1)
struct CTest {
char ch;
char buf[128];
};
#pragma pack(pop)
...
CTest test;
quint16 * dst = (quint16 *) &test.buf[0];
*dst = 5;
qDebug() << dst << *dst;
 
Неужели *dst не будет правильно читаться/писаться если стоит по нечетному адресу ?  Улыбающийся
« Последнее редактирование: Февраль 11, 2015, 13:24 от Igors » Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #8 : Февраль 15, 2015, 13:46 »

Что за мифическое выравнивание? Давайте проверим
А не везде эти прагмы работают. Например последний случай на UC-8410 = http://www.moxa.com/product/UC-8410.htm, ARM процессор, эти прагмы не работают. Выравнивание 4.

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

Код:
CTest test;
quint16 * dst = (quint16 *) &test.buf[0];//допустим buf - нечетный алдрес и выравнивание к 4.
*dst = 5; // если buf на нечетном адресе, то тут ловим ошибку... пишется куданить в сторону. допустим записали в адрес buf-1
qDebug() << dst << *dst; //тут опять ловим ошибку.... опять обращение в сторону и читаем не из адреса buf, а из адреса buf-1
вывод в любом случае будет 5

лучше так проверить
Код:
#pragma pack(push, 1)
char buf[128] = {0};
#pragma pack(pop)
...
buf[1] = 0x34;
buf[2] = 0x12;
quint16 *dst = (quint16 *) &buf[1];
cout << "dst = " << *dst << endl;
*dst = 0xABCD;
cout << "buf[1] = " << buf[1] << "\tbuf[2] = " << buf[2] << endl;
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Февраль 15, 2015, 15:34 »

лучше так проверить
Давайте так (чуть изменил печать)
Код
C++ (Qt)
#pragma pack(push, 1)
char buf[128] = {0};
#pragma pack(pop)
 
buf[1] = 0x34;
buf[2] = 0x12;
quint16 *dst = (quint16 *) &buf[1];
printf("dst = 0x%x\n", (int) *dst);
*dst = 0xABCD;
printf("dst = 0x%x\n", (int) *dst);
 
Вывод
Цитировать
dst = 0x1234
dst = 0xabcd

// если buf на нечетном адресе, то тут ловим ошибку... пишется куданить в сторону. допустим записали в адрес buf-1
С чего Вы это взяли Непонимающий Пишется начиная с того адреса который дали. Просто если он не выровнен, процессор затратит больше времени ("штрафные такты" и все такое) - но никакой ошибки мы не словим
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Февраль 15, 2015, 18:34 »

С чего Вы это взяли Непонимающий Пишется начиная с того адреса который дали. Просто если он не выровнен, процессор затратит больше времени ("штрафные такты" и все такое) - но никакой ошибки мы не словим
Вы ошибаетесь. Точнее пытаетесь судить обо всем по своим знаниям.
А человек выше даже указал процессор, который не умеет читать не выровненные данные.
« Последнее редактирование: Февраль 15, 2015, 18:43 от Old » Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #11 : Февраль 16, 2015, 09:09 »

лучше так проверить
Давайте так (чуть изменил печать)
Код
C++ (Qt)
#pragma pack(push, 1)
char buf[128] = {0};
#pragma pack(pop)
 
buf[1] = 0x34;
buf[2] = 0x12;
quint16 *dst = (quint16 *) &buf[1];
printf("dst = 0x%x\n", (int) *dst);
*dst = 0xABCD;
printf("dst = 0x%x\n", (int) *dst);
 
Вывод
Цитировать
dst = 0x1234
dst = 0xabcd

// если buf на нечетном адресе, то тут ловим ошибку... пишется куданить в сторону. допустим записали в адрес buf-1
С чего Вы это взяли Непонимающий Пишется начиная с того адреса который дали. Просто если он не выровнен, процессор затратит больше времени ("штрафные такты" и все такое) - но никакой ошибки мы не словим

А о чем вообще спор? ТС спросил как из байтового массива получить 2-хбайтное? Ему посоветовали
Цитировать
quint16 n = *(reinterpret_cast<quint16 *>(buf));
Видать ТС новичок и плохо разбирается в привидении типа.  Он этот код использует у себя.... и возможно его buf[0] выровнен к 4. Или у него процессор 8-ми битный. Он в своем коде ни когда не словит ошибку.  Я предостерёг, что пользуясь таким кодом нужно следить за выравниванием. В чем я не прав? Ни кто ему не сказал сделай так
Цитировать
#pragma pack(push, 1)
char buf[128] = {0};
#pragma pack(pop)
quint16 n = *(reinterpret_cast<quint16 *>(buf)
Нужно понимать, что на конкретной архитектуре выравнивание может быть 2 или 4. На некоторых архитектурах не работают прагмы. То, что вы проверили на конкретной архитектуре и заработало - это не значит что будет работать везде. На AVR без прагмы всё будет работать.
ТС использует такое приведение типа без прагмы, как посоветовали, код будет работать. ТС усвоит урок. Потом в другом месте сделает также (или использует этот код)... и обратится по невыровненным данным.... выстрелит себе в ногу. "Прозанимается любовью" с этой багой.... и соскочит на жаву. А потом возникают на форумах холивары, что с/с++ гавно.

Вы в своем коде проследили за выравниванием, т.е. вы прагмами изменили выравнивание к 1. Я говорю тоже самое - нужно учитывать выравнивание.

ps
Код:
*dst = 0xABCD;
printf("dst = 0x%x\n", (int) *dst);
я уже говорил, что такой код не дает проверки. если разыменование *dst происходит неправильно, то вы в неправильный адрес запишите 0xABCD, а потом проверяете прочитав также из неправильного адреса.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Февраль 16, 2015, 13:25 »

Цитированием не злоупотребляйте плз
ТС использует такое приведение типа без прагмы, как посоветовали, код будет работать. ТС усвоит урок. Потом в другом месте сделает также (или использует этот код)... и обратится по невыровненным данным.... выстрелит себе в ногу. "Прозанимается любовью" с этой багой.... и соскочит на жаву. А потом возникают на форумах холивары, что с/с++ гавно.
Трогательная забота о ТС - но у него своя голова есть Улыбающийся А захочет на жабу - тем лучше, слабаки не нужны. Еще до PowerPC я работал на Mac, тогда проц motorola не умел писать в нечет - но он выбрасывал исключение "address must be even". Если опять такой появится и возникнет необходимость его поддержки (Вашу ссылку открыть не могу, но гипотетически это возможно)- ну тогда много чего полетит, и много чего придется переписывать. А до этого не стоит шарахаться от мифических угроз, типа "а вот есть такой проц где.. и тогда, тогда... о ужас!!!"  Улыбающийся Стандарт запрещает писать по невыровненному адресу? Насколько мне известно - нет. Ну и все, а там посмотрим. Заказ на работу с причудливым процом еще надо получить.

Вот куда более реальная проблема: на Вындоуз тип long всегда 4 байта. а вот на Mac он 8 в 64-bit но 4 в 32-bit. Связанные с этим ошибки совсем не редки. Следуя Вашей логике нужно немедленно истребить все long заменив на что-то типа SInt32. Но сделали ли Вы это?  Улыбающийся
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #13 : Февраль 16, 2015, 15:55 »

Стандарт запрещает писать по невыровненному адресу? Насколько мне известно - нет. Ну и все, а там посмотрим. Заказ на работу с причудливым процом еще надо получить.
Если на конкретной архитектуре выравнивание 4, то с подобным приведением типа вы должны позаботиться о выравнивании. либо вы должны чтобы buf был кратен 4, либо вы должны указать прагмой нужное выравнивание. выравнивание 4 - это не мифический процессор. Вот  http://www.moxa.com/product/UC-8410.htm - вполне не мифическая микроЭВМ с немифическим Intel XScale IXP435 533 MHz processor.


Цитировать
Что за мифическое выравнивание? Давайте проверим
Код

Цитировать
#pragma pack(push, 1)
struct CTest {
 char ch;
 char buf[128];
};
#pragma pack(pop)
...
CTest test;
quint16 * dst = (quint16 *) &test.buf[0];
*dst = 5;
qDebug() << dst << *dst;


Неужели *dst не будет правильно читаться/писаться если стоит по нечетному адресу ?
Смешно както.... "Что за мифическое выравнивание? Давайте проверим" - и тут же приводите проверочный код, в котором вы позаботились о выравнивании. Если это выравнивание мифическое, зачем вы прагмой изменили выравнивание к 1? Ваш проверочный код выровнен к 1. И данные выровнены к 1. Можно спокойно обращаться к адресам кратным 1. Вы проверьте без выравнивания.

Цитировать
шарахаться от мифических угроз, типа "а вот есть такой проц где.. и тогда, тогда... о ужас!!!"
От каких мифических угроз?  На любом процессоре и любой архитектуре, если делаешь привидение типа
Код:
quint16 n = *(reinterpret_cast<quint16 *>(buf));
проследи, чтобы буф был выровнен. если по дефолту выравнивание 4 - смотри чтоб буф был выровнен к 4. Если ваш буф по нечетному адресу, то измени выравнивание к 1 (хотя не везде это сработает). Так или иначе, но программист обязан следить за выравниванием, при подобном приведении типа. В чем я не прав?

С ваших слов, выравнивание это миф и о нем заботиться не нужно. И в качестве доказательства приводите пример с выровненными данными. В чем смысл?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Февраль 16, 2015, 17:37 »

От каких мифических угроз?  На любом процессоре и любой архитектуре, если делаешь привидение типа
Код:
quint16 n = *(reinterpret_cast<quint16 *>(buf));
проследи, чтобы буф был выровнен. если по дефолту выравнивание 4 - смотри чтоб буф был выровнен к 4. Если ваш буф по нечетному адресу, то измени выравнивание к 1 (хотя не везде это сработает). Так или иначе, но программист обязан следить за выравниванием, при подобном приведении типа. В чем я не прав?
Возможно Вы имели ввиду нечто типа
Код
C++ (Qt)
struct CTest {
 char ch;
 quint16 val;
};
CTest test;
...
 
quint16 n = *(reinterpret_cast<quint16 *> (&test.ch + 1);
 
Да, это неверно, n будет совсем не test.val, до которого еще 1 байт. Да, если сделаем #pragma pack 1 для CTest - тогда будет верно. С этим никто не спорит, но это совсем не значит что reinterpret_cast что-то "не так приводит" или читается/пишется куда-то "налево". reinterpret_cast четко работает с тем адресом что дали. Напр если это &test.val - то он и будет читаться/писаться, какое бы выравнивание ни стояло.

Если на конкретной архитектуре выравнивание 4, то с подобным приведением типа вы должны позаботиться о выравнивании. либо вы должны чтобы buf был кратен 4, либо вы должны указать прагмой нужное выравнивание. выравнивание 4 - это не мифический процессор. Вот  http://www.moxa.com/product/UC-8410.htm - вполне не мифическая микроЭВМ с немифическим Intel XScale IXP435 533 MHz processor.
Я открыл ссылку, поискал "align" - не нашел. Пожалуйста "ткните носиком".  
« Последнее редактирование: Февраль 16, 2015, 17:39 от Igors » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.171 секунд. Запросов: 22.