I want to ask if there is difference between this two array passing method:
unsigned char array[100];
function(array);
Where:
library.cpp
uint8_t LibraryClass::function(unsigned char array[]) { }
library.h
uint8_t function(unsigned char array[]);
And this:
unsigned char array[100];
function(array);
Where:
library.cpp
uint8_t LibraryClass::function(const unsigned char* array) { }
library.h
uint8_t function(const unsigned char* array);
My questions is:
There is difference between this to methods?
Additional question:
My MCU need to do additional operation in method 1 instead of method 2?
There is additional const in method 2, why is used? It is safety to use const when using pointers?
unsigned char array[] is just syntactic sugar for unsigned char *array in a function declaration. They're literally identical.
The const means that function guarantees not to modify the contents of array. The first example makes no such guarantee to the caller.
Normally in c/c++ unsigned char array[] is unsigned char* array which consists of contiguous memory.
Whenever an array is passed to a function it is treated as pointer(*) denoting the base address.
Mentioning const- (const unsigned char* array) denotes its value will not change.
Related
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.
According to these answers a buffer of bytes should be unsigned char, either because of convention or maybe the padding guarantees, I'm not sure. I have a function that looks something like:
saveDataToFile(const unsigned char* data, size_t size);
I find that I keep having to cast when I have a vector of char or an std::string or a string literal or something, and my code ends up looking like:
const char* text = "text";
saveDataToFile(text, 4); // Argument of const char* is incompatible with parameter of type const unsigned char*
saveDataToFile(reinterpret_cast<const unsigned char*>(text), 4);
Is there a way to avoid doing this all the time? Someone once mentioned to make my function take const char* instead of unsigned, but that doesn't really as then I'd have to cast the other way. For example std::string has .c_str() and .data() that return signed and unsigned. I also thought about taking void*, maybe that's the best way?
Perhaps the simplest way, as you have suggested yourself, is to make the function's first argument a const void* and then cast that to whatever is needed inside the function. This way, you also avoid using a reinterpret_cast and can safely use a static_cast:
void saveDataToFile(const void* data, size_t size)
{
const uint8_t* local = static_cast<const uint8_t*>(data);
//.. do something with the cast pointer ...
}
int main()
{
double dData = 33.3;
int16_t sData = 42;
char cData[] = "Hello, World!";
saveDataToFile(&dData, sizeof(dData));
saveDataToFile(&sData, sizeof(sData));
saveDataToFile(cData, sizeof(cData));
return 0;
}
A more "Pure C++" way (in some folks' eyes, maybe) would be to make a templated function. However, the disadvantages here are: (a) you will need a reinterpret_cast in this case; and (b) the compiler will (probably) generate separate function code for each of the different argument types used:
template<typename T>
void saveDataToFile(const T* data, size_t size)
{
const uint8_t* local = reinterpret_cast<const uint8_t*>(data);
//.. do something with the cast pointer ...
}
I have an API which requests a char*, this is my API function:
CANMessage(unsigned _id, const char* _data, char _len = 8)
More information available here: https://os.mbed.com/docs/mbed-os/v5.11/mbed-os-api-doxy/classmbed_1_1_c_a_n_message.html
I would like to call this function from within another function, but I am getting confused about const char* and casting. I want to call this function from function foo(), like so:
void foo(unsigned int id, /*???*/ data, char len) {
CANMessage(id, data, len)
}
So I need to pass id, data and len to function foo. My problem is that the data coming in is a uint8_t type. I got a vector of uint8_t, where the address of the first element is the one I need to pass:
vector<uint8_t> dta;
Which I tried to pass as &dta[0]: foo(idNo, &dta[0], length)
With the foo function as so:
void foo(unsigned int id, uint8_t* data, char len) {
CANMessage(id, (char*)data, len)
}
But I get "Argument of type std::uint8_t * is incompatible with parameter of type char*
How do I pass it as const char* when function foo, which calls it, accepts uint8_t*?
Please note I can't change types, dta has to stay vector<uint8_t>.
std::uint8_t ιs equal to unsigned char.
This is different from plain char or signed char, but all of them are 8 bit, therefore casting would techically work.
It's common that many functions that would otherwise need a "buffer" have a char* in their definition instead of the proper unsigned char*. Therefore, casting would most probably be harmless.
In the case that the function actually wants characters but not a buffer, then you have a problem because the types are different, and whether you will have an issue or not is undefined.
Since you are in an environment where std::uint8_t is available, the char types must be max 8 bits, but just to make sure you're not on a machine with 7 bit char's, add a static_assert.
reinterpret_cast the uint8_t* to const char* and static_cast the size (size_t) of the vector to char.
void foo(unsigned _id, const std::vector<uint8_t>& dta) {
static_assert(CHAR_BIT == 8, "Strange char");
CANMessage(
_id,
reinterpret_cast<const char*>(dta.data()),
static_cast<char>(dta.size())
);
}
I am a web developer and I am new to C++. I am using Qt C++. I was looking a way to generate a PBKDF2 key in Qt, but could not find a way to do that in pure C++. So looking on internet I have found this small C implementation https://github.com/ctz/fastpbkdf2. I need to use the following function
void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw,
const uint8_t *salt, size_t nsalt,
uint32_t iterations,
uint8_t *out, size_t nout)
In my C++ file, I have
QString password = "password";
QString salt = "salt";
int iterations = 30000;
I know I can directly call any C function in C++, but I am not sure about how can I call that function with those parameters from my C++ file. An explanation of data type conversions would also be appreciated.
All you need to convert QString to char (or uint8_t):
QString passoword = "password";
QByteArray ba = password.toLatin1();
const uint8_t *pw = (const uint8_t*)ba.data();
And you can use this pw in the function. The same for "salt". You can use "iterations" as it is. For "out" parameter, allocate uint8_t with any method you prefer, could be malloc.
uint8_t is a typedef for an unsigned 8-bit integer, or in other words an unsigned char.
uint32_t is a typedef for an unsigned 32-bit integer, or in other words an unsigned int.
These typedefs are defined in stdint.h. These types were introduced to have well-defined (width-wise) integer types for portability.
size_t is typically an unsigned integer type as well. So the
prototype:
void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw,
const uint8_t *salt, size_t nsalt,
uint32_t iterations,
uint8_t *out, size_t nout)
is equivalent to:
void fastpbkdf2_hmac_sha256(const unsigned char* pw, unsigned int npw,
const unsigned char* salt, unsigned int nsalt,
unsigned int iterations,
unsigned char* out, unsigned int nout);
Others have posted how to convert QString into a unsigned character array.
I am not too familiar with QT so I am looking at this page as a reference for a QString. It appears to be a managed string object while the function you want to call just wants a null terminated array of uint8_ts. I think it is wrapping std::string because there is a toStdString() member function. A std::string just manages a character array which is what your function wants so you can do this: password.toStdString().c_str() to get the char *.
Most platforms will implicitly convert uint8_t and char since they are almost always straight up 1 byte of memory.
There is also an output buffer and by the calling convention it looks like you have to manage that memory. From glancing at the docs of the github you linked it will output however much memory you tell it to using nout. In this example we create a 256 byte buffer for it to output to.
QString password = "password";
QString salt = "salt";
int iterations = 30000;
const size_t nout = 256;
uint8_t * out = new uint8_t[nout];
fastpbkdf2_hmac_sha256(password.toStdString().c_str(), password.toStdString().size(),
salt.toStdString().c_str(), salt.toStdString().size(),
iterations,
out, nout);
// use out
delete[] out;
I have this array
unsigned char bit_table_[10][100];
What is the right way to fill it with 0.
I tried
std::fill_n(bit_table_,sizeof(bit_table_),0x00);
but vc 2010 flags it as error.
On initialization:
unsigned char bit_table_[10][100] = {};
If it's a class member, you can initialize it in the constructor, like this:
MyClass::MyClass()
:bit_table_()
{}
Otherwise:
std::fill_n(*bit_table_,sizeof(bit_table_),0);
The type of bit_table_ is unsigned char [10][100], which will decay (that is, the compiler allows it to be implicitly converted to) into unsigned char (*)[100], that is, a pointer to an array of 100 unsigned chars.
std::fill_n(bit_table_, ...) is then instantiated as:
std::fill_n(unsigned char (*)[100], ...) which means it expects a value of type unsigned char [100] to initialize bit_table_ with. 0 is not convertible to that type, so the compilation fails.
Another way to think about it is that the STL functions that deal with iterators only deal with a single dimension. If you are passing in a multidimensional structure those STL functions will only deal with a single dimension.
Ultimately, you can't do this; there is no way to assign to an array type. I.e., since you can't do this:
char table[100];
char another_table[100]= { };
table= another_table;
you can't use std::fill_n on multidimensional arrays.
You can also try unsigned char bit_table_[10][100]= { 0 } to fill it with zeros.
int main()
{
unsigned char bit_table_[10][100]= { 0 };
return 0;
}