Cast C-style array of pointers to const - c++

I am currently working with a C-API (OpenSSL) and there are a lot functions declared like the following:
// From bytes to TYPE
TYPE *d2i_TYPE(TYPE **a, unsigned char **ppin, long length);
// From TYPE to bytes
int i2d_TYPE(TYPE *a, unsigned char **ppout);
But sometimes, functions expect a pointer to an array of pointers to some const type:
// From bytes to TYPE
TYPE *d2i_TYPE(TYPE **a, const unsigned char **ppin, long length);
Notice the const unsigned char ** vs unsigned char ** and ignore the functions' first argument.
Now consider the following example, where some input data is given as non-const pointers. What is the correct way of casting the array of pointers to an array of pointers const? And also, since the function expects a pointer, the parameter must be an lvalue. I am guessing this is the reason there is no implicit cast..
int length = 42;
unsigned char * data = new unsigned char[length];
// Error C2664: cannot convert argument 2 from 'unsigned char **' to 'const unsigned char **'
TYPE * my_typeE = d2i_TYPE(nullptr, &data, length);
// My solution:
auto x = reinterpret_cast<unsigned char const *>(data);
auto y = const_cast<unsigned char const *>(data);
TYPE * my_typeX = d2i_TYPE(nullptr, &x, length);
TYPE * my_typeY = d2i_TYPE(nullptr, &y, length);
Are there other solutions that are possibly easier to read?

No need of cast:
const unsigned char* z = data;
[[maybe_unused]]TYPE * my_typeZ = d2i_TYPE(nullptr, &z, length);
Demo

Related

C++ pointer to pointer of array

how to pass array to this function ?
this is the function :
void fire(const uint8_t *const s[])
{
cout<<*s<<endl;
}
and I want to pass this array to that :
unsigned char X[10] = {255,255,255,255};
it is done by this and it works
unsigned char X[5] = {255,255,255,255};
unsigned char *pointertoX ;
pointertoX = X;
fire(&pointertoX);
why I need *pointertoX ?
is there any other way for do this ?
whole code :
#include <iostream>
using namespace std;
void fire(const uint8_t *const s[])
{
cout<<*s<<endl;
}
int main() {
unsigned char X[10] = {255,255,255,255};
unsigned char *pointertoX ;
pointertoX = X;
fire(&pointertoX);
return 0;
}
note : I'm trying to pass bitmap to ffmpeg "sws_scale" ..
https://ffmpeg.org/doxygen/4.1/group__libsws.html#gae531c9754c9205d90ad6800015046d74
this is the function :
void fire(const uint8_t *const s[])
That function accepts a pointer to a const pointer to a const uint8_t.
and I want to pass this array to that :
unsigned char X[10] = {255,255,255,255};
You cannot.
In order to pass an array into a function that accepts a pointer, the function would have to accept a pointer to element type of that array (after other implicit conversions such as pointer from to non-const into pointer to const). The element of that array is unsigned char, while the function accepts a pointer to a const pointer to a const uint8_t.
why I need *pointertoX ?
Because the function accepts a pointer to a const pointer to a const uint8_t, and &pointertoX is a pointer to a pointer to an unsigned char. Given that uint8_t is an alias of unsigned char, &pointertoX is implicitly convertible to the function parameter.
note : I'm trying to pass bitmap to ffmpeg "sws_scale" ..
Read the documentation carefully:
srcSlice the array containing the pointers to the planes of the source slice
dst the array containing the pointers to the planes of the destination image
You're trying to pass an array of characters into a function that expects an array of pointers.
P.S. The behaviour of the program is undefined because *s does not point to a null terminated string, but you insert it into a character stream which has such requirement.

char array to unsigned char *

So i have this function which receives a pointer:
int myfunc( const char *token, unsigned char *plaintext )
I do my stuff and i end up with a char array:
unsigned char my_plaintext[1024];
Now i need to set that pointer (plaintext) to what's in my_plaintext.
I've tried many different ways but i haven't yet figure this one out...
This part is in a cpp file, and i've even tried:
std::string tmpstr( my_plaintext );
But this comes back with:
token_crypto.cpp:131:13: error: invalid conversion from 'char*' to 'unsigned char*' [-fpermissive]
my_plaintext
^~~~~~~~~~~~
And
std::string tmpstr( (char *)my_plaintext );
'�5�B'
this does compiles but the content is all wrong:
EDIT:
The content of my_plaintext is fine:
int myfunc( const char *token, unsigned char *plaintext ) {
unsigned char my_plaintext[1024];
... some processing stuff (specifically gcm_decrypt) to which is pass my_plaintext ...
cout << my_plaintext
// prints: hello:world
but then however i try set the contents of plaintext to whatever is in my_plaintext either fails at compilation or prints some weird characters.
If you know that plaintext already points at an array that is 1024 long (or longer) then you can use memmove():
int myfunc( const char *token, unsigned char *plaintext )
{
unsigned char my_plaintext[1024];
/* ... fill in my_plaintext here ... */
memmove(plaintext, my_plaintext, 1024);
/* ... rest of function ... */
}
Note that the parameters to memmove are destintation and then source rather than the other way round.
It's up to the caller of your function to make sure the pointer they pass in points to at least 1024 bytes.
You can use memcpy() instead in this case, but using memmove() is good practice in general.
The C++ string constructor doesn't take an unsigned char *. See the C++ reference here:
http://www.cplusplus.com/reference/string/string/string/
You need to cast the unsigned char array to a char array. See how to do that here:
How to Convert unsigned char* to std::string in C++?

Making strncmp() accept unsigned char * as an argument

I have a pointer to a string which is "unsigned char *" and i want to use it as an argument in strncmp() function.
But compiler complains:
invalid conversion from 'unsigned char*' to 'const char*'
How can i make:
strncmp(const char *a, unsigned char *b, size_t size);
work?
Is there any workaround?
You can safely cast unsigned into signed.
unsigned char * p2 = ...;
strncmp(px, (char *)p2, 5);
should work.
unsigned char * p2 = ...;
char * p3 = static_cast<char *>(p2);
This maybe overkill.
Not sure why you're using unsigned char*, but if you need to, use a cast. For example :
strncmp(a, (char*)b, 10);
use reinterpret_cast to convert it. Something like this -
strncmp(const char *a, reinterpret_cast<const char*>(unsigned char
*b), size_t size);

unsigned char array incompatible with pointer parameter

I have this function
unsigned char NCN_System_upload(unsigned char *data, unsigned char len);
I have an array defined as such:
unsigned char data[3];
I'm using the function as the following:
NCN_System_upload(&data, 3);
However, I get the following error:
argument of type unsigned char (*)[3] is incompatible with parameter of type unsigned char*
Why doesn't this work?
The name of the array is already (can be implicitly converted) to a pointer to its beginning. Thus, you should do it like this:
NCN_System_upload(data, 3);

Cannot initialize a parameter of type "const unsigned char *" with an rvalue of type 'value_type *' (aka char*)

I get an error "Cannot initialize a parameter of type "const unsigned char *" with an rvalue of type 'value_type ' (aka char)" in the following lines.
image->initWithImageData(&(buffer->front()),buffer->size());
buffer is of type std::vector<char> *buffer
and the above error in on &(buffer->front() does anybody know how to fix it?
The const is not a problem, but you need to cast the pointer - this isn't recommended generally but if you don't have another choice, you can do one of the following
char *a = buffer->data();
const unsigned char *b= reinterpret_cast<unsigned char *>(a);
or plain C style
const unsigned char *b= (const unsigned char *)(a);