2016-03-31 10 views
6

W moim programie pracuję dużo z komunikacją szeregową, dlatego bardzo często używam QByteArray.Czy istnieje krótszy sposób inicjowania QByteArray?

Zastanawiałem się, czy istnieje krótsza droga do zainicjowania QByteArray ze specyficznymi bajtów niż:

const char test_data[] = { 
    static_cast<char>(0xB1), static_cast<char>(0xB2), 
    0x5, static_cast<char>(0xFF), 
    static_cast<char>(0xEE), static_cast<char>(0xEE), 
    static_cast<char>(0x0)}; // Note QByteArray should be able to hold 0 byte 
const QCanBusFrame frame = QCanBusFrame(0xA1, QByteArray(test_data)); 

static_cast<char> jest konieczne, ponieważ w przeciwnym wypadku C++ 11 daje błąd o zwężenie, ponieważ zakres do 0x7F 0xFF jest większy niż char, może pasować - ale char jest tym, o co prosi konstruktor QByteArray.

To QByteArray konstruktor używany:

QByteArray::QByteArray(const char *data, int size = -1)

+0

Co się dzieje, kiedy deklarujemy 'test_data' jako unsigned char array (unsigned char *), a następnie przesłać ją do tablicy char (char *)? – OnurA

+0

@OnurA Czy na pewno chcesz użyć gwiazdki? Linia, w której znajduje się 'test_data' rzuca" nieprawidłową konwersję z 'int' na 'const unsigned char * " – DBedrenko

+0

Możesz łatwo utworzyć funkcję, która utworzy' QByteArray' z tym, co chcesz, jako argument. – Garf365

Odpowiedz

2

Będąc zainspirowany powyższych odpowiedzi jest to, co w końcu wymyślił:

const quint8 testData[] {0xB1, 0x00, 0xB2, 0x00}; 
const QCanBusFrame cFrame = QCanBusFrame(
    0xA1, QByteArray(reinterpret_cast<const char*>(testData), sizeof(testData))); 

wolę mieć bajty jak numery bajtowych raczej niż literalna znaków podczas pracy z komunikacją szeregową.

Po omówieniu ## C++ poinformowano mnie, że reinterpret_cast jest odpowiednio używany w tej sytuacji.

0

Czy próbowałeś następujące:

const unsigned char test_data[] = { 
    static_cast<char>(0xB1), static_cast<char>(0xB2), 
    0x5, static_cast<char>(0xFF), 
    static_cast<char>(0xEE), static_cast<char>(0xEE), 
    static_cast<char>(0xB3)}; 
const QCanBusFrame frame = QCanBusFrame(0xA1, QByteArray((char*)test_data)); 

Używasz konstruktora: QByteArray::QByteArray(const char *data, int size = -1).

Jeśli rozmiar jest ujemny, zakłada się, że dane wskazują ciąg zakończony nulem, a jego długość jest ustalana dynamicznie. Znak kończący nul nie jest uważany za część tablicy bajtów.

+0

, ale byłbym ostrożny z zerem i przekazałbym rozmiar tablicy jako argument. – OnurA

+1

Po prostu próbowałem i kompiluje się pomyślnie. Działa bez "static_cast" (cała korzyść z twojego rozwiązania polega na tym, że te rzuty nie są potrzebne). Nie jestem pewien, na co powinienem uważać przy pomocy 0 bajtów: muszę również móc użyć 0 bajtów. – DBedrenko

+1

Należy koniecznie wywołać 'QByteArray ((char *) test_data, sizeof (test_data));'! Pojedynczy parametr ctor (lub o rozmiarze == -1) spróbuje skopiować dane jako zwykły ciąg znaków c, który musiałby być zakończony znakiem null! – Aconcagua

2

tak:

const unsigned char str[] = {0xff, 0xed, 0xba, 0xd1}; 
QByteArray ba(reinterpret_cast<const char*>(&str[0]),std::extent<decltype(str)>::value); 

teraz konstruktor QByteArray wygląda dziwnie, ale sekwencje bajtów są jasne. Możesz także dodać kończący 0-bajtowy do tablicy zamiast używać std::extent, ale ogólnie możesz mieć zero bajtów w środku sekwencji.

+0

Tylko z powodu ciekawości, czy możesz wyjaśnić, dlaczego reinterpret_cast i std :: extent są niezbędne? – OnurA

+1

Podoba mi się reinterpret_cast (styl C++, nie C). Zamiast rozmiaru, po prostu użyj sizeof (str) ... – Aconcagua

+0

Nie możesz po prostu rzucić str zamiast & str [0] (wygląda dla mnie brzydko)? Przynajmniej GCC akceptuje ... – Aconcagua

17

Proste i skuteczne:

QByteArray b = QByteArrayLiteral("\x12\x00\xa4\x42\x51\x00\x00\x99"); 
+0

Hmm Nie widzę "QByteArrayLiteral" udokumentowanego gdziekolwiek, ale na Boga działa lepiej niż dokładnie ten sam argument przekazany do 'QByteArray', ponieważ" \ x00 "nie są traktowane jako terminator ciągu znaków . To samo można osiągnąć za pomocą 'QByteArray', ale musisz podać poprawny argument' size'. Nie jest to złe rozwiązanie, dzięki :) – DBedrenko

+1

@DBedrenko To tylko makro: http://doc.qt.io/qt-5/qbytearray.html#QByteArrayLiteral – rbaleksandar

+0

Zastanawiam się, co [udokumentowane] (https: //codereview.qt -project.org/#/c/195544/), że ... – peppe

2

Jako alternatywę dla QByteArrayLiteral, można toczyć własną rękę, jeśli chcesz:

#include <QByteArray> 

template <int N> QByteArray arrayFromLiteral(const char (&data)[N]) { 
    return QByteArray::fromRawData(data, N-1); 
} 

int main() { 
    const auto arr = arrayFromLiteral("\xB1\xB2\0\1"); 
    Q_ASSERT(arr.size() == 4); 
    Q_ASSERT(arr[0] == (char)0xB1); 
    Q_ASSERT(arr[1] == (char)0xB2); 
    Q_ASSERT(arr[2] == (char)0x00); 
    Q_ASSERT(arr[3] == (char)0x01); 
} 
1

Może być prace powoli:

QByteArray ba = QByteArray::fromHex(QVariant("B1B2FFEEEE00").toByteArray()); 
Powiązane problemy