I'm working on a mesh where every node take a picture, encode it in base64 and send the result to the root node. The encoded array is 'unsigned char' but the function used to send the data to the root node via mesh accepts a String. And if I try to create a String from the 'unsigned char' array I get the error: invalid conversion from 'unsigned char' to 'const char*'*.
unsigned char* base64 = (unsigned char*)heap_caps_malloc(4*(_jpg_buf_len/3)+1, MALLOC_CAP_8BIT);
if (base64 == NULL)
Serial.println("Can not malloc memory");
unsigned int base64_length = encode_base64(_jpg_buf, _jpg_buf_len, base64); //unsigned int encode_base64(unsigned char input[], unsigned int input_length, unsigned char output[]);
String to = bridgeNodeName;
mesh.sendSingle(to, base64); //bool painlessMesh::sendSingle(uint32_t dest, String &msg)
{ //start block
String base64str;
if (!base64str.reserve(4*(_jpg_buf_len/3)+1)) {
Serial.println("Can not malloc memory");
} else {
unsigned int base64_length = encode_base64((unsigned char*)base64str.c_str(),
base64str.length(), base64); //unsigned int encode_base64(unsigned char input[], unsigned int input_length, unsigned char output[]);
// clean up the string
base64str[base64_length] = '\0'; // this is a bit naughty as the base64str.length() is no longer correct, but it should work.
mesh.sendSingle(to, base64str);
}
} // end block to recover base64str memory
Thanks you caught my stuff up, again
How about this
{ //start block
String base64str;
if (!base64str.reserve(4*(_jpg_buf_len/3)+1)) {
Serial.println("Can not malloc memory");
} else {
unsigned int base64_length = encode_base64(_jpg_buf,
_jpg_buf_len, (unsigned char*)base64str.c_str()); //unsigned int encode_base64(unsigned char input[], unsigned int input_length, unsigned char output[ ]);
// clean up the string
base64str[base64_length] = '\0'; // this is a bit naughty as the base64str.length() is no longer correct, but it should work.
mesh.sendSingle(to, base64str);
}
}
The null terminator is added by the call to encode_base64() so it’s not required to add one manually
Just to be picky - Technically in c++ you should usually try to stay clear from c style casting and casting a const char * back into a char* should be a red flag. (And using const_cast to try and modify a read-only object is undefined behavior)
You rely on your understanding of how the String class is working (which breaks the encapsulation rule) and understanding of how gcc deals with the pointers and memory allocation … So this should not be recommended (but will likely work).
I agree entirely. You should not cast const char* to a char* unless you really know what you are doing and what the result will be.
A nasty solution to avoid double memory allocations.
Perhaps there is a better one.
We could look at
mesh.sendSingle( .. ) and see if it can be modified to take the const char* base64 directly.