C ++ Qt: побитовые операции - PullRequest
3 голосов
/ 02 июня 2009

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

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

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

Ответы [ 3 ]

5 голосов
/ 02 июня 2009

Посмотрим, сможем ли мы получить это правильно

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 ) ;
}
1 голос
/ 02 июня 2009

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

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 голосов
/ 02 июня 2009

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

#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;
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...