2009-06-02 4 views
3

Я работаю над небольшим проектом для колледжа, и мне нужно моделировать передачу по сети, а также внедрять и визуализировать различные типы алгоритмов коррекции ошибок. Мой импровизированный пакет состоит из одного quint8: мне нужно преобразовать его в бит-массив, например QBitArray, добавить к нему контрольный бит, передать его по UDP, проверить успешность передачи с битом проверки и затем построить из нее quint8 , Еще раз, это не практично, но образовательная задача, так что не предложить мне использовать реальные algoriths как CRC ...C++ Qt: побитовые операции

Так что мой вопрос: как преобразовать любой тип данных (в данном случае quint8) в QBitArray? Я имею в виду, что любые данные на компьютере представляют собой бит-массив, но как мне получить доступ к этому вопросу.

Спасибо, Дмитрий.

ответ

5

Давайте посмотрим, если мы можем получить его правильно

template < class T > 
static QBitArray toQBit (const T &obj) { 
    int const bitsInByte= 8; 
    int const bytsInObject= sizeof(T); 

    const quint8 *data = static_cast<const quint8*>(&obj) ; 
    QBitArray result(bytsInObject*bitsInByte); 
    for (int byte=0; byte<bytsInObject ; ++byte) { 
     for (int bit=0; bit<bitsInByte; ++bit) { 
      result.setBit (byte*bitsInByte + bit, data[byte] & (1<<bit)) ; 
     } 
    } 
    return result; 
} 

void Foo() { 
    Bar b ; 
    QBitArray qb = toQBit (b) ; 
} 
+0

Спасибо, это то, что я хотел. Typo в строке 6: quint8 вместо qint8. – Dmitri

+0

вы - welcom, опечатка исправлена – TimW

1

qint8 фактически подписан знак. Таким образом, вы можете рассматривать ваши объекты как массив символов.

template < class T > 
QBitArray toQBit (T &obj) { 
    int len = sizeof(obj) * 8 ; 
    qint8 *data = (qint8*)(&obj) ; 
    QBitArray result ; 
    for (int i=0; i< sizeof(data); ++i) { 
     for (int j=0; j<8; ++j) { 
      result.setBit (i*8 + j, data[i] & (1<<j)) ; 
     } 
    } 
    return result; 
} 

void Foo() { 
    Bar b ; 
    QBitArray qb = toQBit (b) ; 
} 
+0

Программа выйдет из строя ... в вашем коде есть как минимум 2 ошибки. – TimW

0

Я не вижу смысла в объявлении функции шаблона, а затем бросая свой аргумент Uint8. Решения для типов, которые могут быть повышены до неподписанного долгого

#include <bitset> 
template <typename T> 
QBitArray toQBit(T val) { 
    std::bitset<sizeof(T) * 8> bs(val); 
    QBitArray result(bs.size()); 
    for (int ii = 0; ii < bs.size(); ++ii) { 
     result.setBit(ii, bs.test(ii)); 
    } 
    return result; 
} 

Там нет никакого способа родового преобразовать любой тип данных битового массива. Особенно, если ваш тип данных содержит указатели, вы, вероятно, хотите перенести указатель, а не указатель. Поэтому любой сложный тип следует рассматривать отдельно. И будьте в курсе различных эндианн (мало-северных и big-endian) в разных архитектурах. Я думаю, что std :: bitset безопасен в соответствии с этой проблемой, но, например, литье указателя на struct в массив символов и сохранение его битов может быть небезопасным.

Смежные вопросы