0

How can I convert QByteArray coming from QFile::readAll() into a uint8_t array(uint8_t*)?

I tried static_cast<>() but didn't seemed to work for whole array.

examples of what I've done with static_cast:

uint8_t* x = new uint8_t;
x[0] = static_cast<uint8_t>(testWav.readAll()[0]);
uint8_t* x = new uint8_t;
*x = static_cast<uint8_t>(*testWav.readAll());

etc. didn't work

kaan kaya
  • 5
  • 5

2 Answers2

2

This doesn't do what you want.

 uint8_t* x = new uint8_t;
 x[0] = static_cast<uint8_t>(testWav.readAll()[0]);

This way you copy only [0] element of array. The rest of allocated memory stay uninitialized

This cannot work at all:

uint8_t* x = new uint8_t;
*x = static_cast<uint8_t>(*testWav.readAll());

QByteArray is a class-type of dynamic container, so you can't use static_cast to access its data as an array, it's a principally different, incompatible data structure. And you're still assigning only the first element: *x is an equivalent of x[0].

QByteArray has method QByteArray::data() which returns a pointer to char*: https://doc.qt.io/qt-6/qbytearray.html#data

The pointer returned by data() isn't owning one and points to memory allocated by class, so data contained in QByteArray which returned by readAll() will cease to exist at end of statement containing it, unless it's assigned to a more persistent storage:

QByteArray fileContent = file.readAll();
char *buffer = fileContent.data();

Result of fileContent.size() would give the actual size of buffer. Note that in some cases it's more convenient to work with QByteArray instead of a raw pointer. You need conversion ONLY if you have to use some API taking raw pointer or face some performance issues.

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
  • I did `char* data = testFile.readAll().data();`, but then how can I turn char array to uint8_t array? – kaan kaya Feb 01 '23 at 07:15
  • note that OP makes the static cast on one element of the array, not the whole `QByteArray` – 463035818_is_not_an_ai Feb 01 '23 at 07:15
  • @kaankaya you can't do that in one line, that pointer will point at freed memory, because QByteArray will cease to exist as a temporary. – Swift - Friday Pie Feb 01 '23 at 07:16
  • @463035818_is_not_a_number that's another problem, that's likely isn't the intended result, because whole content of file will be lost after that supposed action. – Swift - Friday Pie Feb 01 '23 at 07:17
  • @kaankaya why do you think you need to convert the `QByteArray` ? What do you need the `uint8_t` array for, and why can you not use the `QByteArray` for that ? It looks like there is a misunderstanding somewhere and we are helping at the wrong end – 463035818_is_not_an_ai Feb 01 '23 at 07:19
  • I do a crc16 calculation and it needs bytes-uint8_t* it doesn't work correctly when I do it with const char* or char* – kaan kaya Feb 01 '23 at 07:35
  • @kaankaya the horrible implementation of crc16 aside that might be the case when use of raw pointer to buffer is OK. `uint8_t` and `unsigned char` is usually same type unless you have rather weird platform where char isn't a 8-bit byte, i.e. it's not a standard compiler. – Swift - Friday Pie Feb 01 '23 at 07:40
  • @Swift-FridayPie I normally calculated crc16 on a hex string, turned it to uint8_t and the calculation is correct. Now I just want to do it for a file's data. I work on msvc qt – kaan kaya Feb 01 '23 at 07:45
  • @kaankaya your implementation was correct in C but is not type-correct in C++ until ISO C++20 . Mostly because of implicit upgrade of bitwise operation result to a signed int. You can peek here: https://stackoverflow.com/questions/10564491/function-to-calculate-a-crc16-checksum – Swift - Friday Pie Feb 01 '23 at 07:48
  • also, MSVC is a "weird" not-quite-standard compiler. It's likely was raising run-time check exceptions on assignments there unless you do proper multiplication with a mask. WHich doesn't work with signed. – Swift - Friday Pie Feb 01 '23 at 07:52
0

I think first you need to know that a pointer is not an array. And that you cannot assing a c-array as a whole.

Then you should reconsider if you actually need to convert anything. QByteArray grants you access to the underlying array via its data member. (I find it a bit unfortunate that QByteArray is based on char rather than unsigned char, so you'd want to check whether char is signed or not).

Eventually, if you still want, you can write a loop to copy elements from the QByteArray to another array.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185