cannot convert parameter 1 from 'char *' to 'uint8_t *' - c++

void OnReceived(std::shared_ptr<uint8_t> buffer, int len) {
.........
}
int main(){
std::vector<char> buffer(1000);
OnReceived((std::shared_ptr<uint8_t>)buffer.data(),rcvlen);
}
am trying to cast it but i cant i dont know why!!!
Error 1 error C2664: 'std::tr1::_Ptr_base<_Ty>::_Reset0' : cannot convert parameter 1 from 'char *' to 'uint8_t *' c:\program files\microsoft visual studio 10.0\vc\include\memory 1705
so how can i convert it?

You really don't want to do that. Aside from the fact that char and uint8_t may be distinct types, even if you force the code to compile, your buffer will be deallocated twice, likely crashing your program. Just change OnReceived to accept a raw pointer.

Beyond the type mismatch, you don't want to do that. It'll almost cause a crash when both the vector destructor and the shared_ptr deallocate the same memory. You should consider boost::shared_array or a shared pointer to the entire vector (shared_ptr<std::vector>) instead of what you're doing now. Or as Igor suggests, OnReceived could be changed to accept a raw pointer if it doesn't need shared ownership of the buffer.

uint8_t is an unsigned char so you'll either need to change the type of buffer or reinterpret_cast somewhere along the line.

buffer.data() will return a char *. You're trying to cast that to a std::shared_ptr - in other words, construct a shared_ptr out of it. In its implementation it tries to assign the pointer but can't since you're passing in an incompatible pointer type.
Try casting it to the appropriate type before passing it in, such as:
OnReceived((std::shared_ptr<uint8_t>)(uint8_t *)buffer.data(),rcvlen);
or, probably a better solution, convert your std::vector to a vector of uint8_t.

Related

Why can you cast a integer as a void pointer but can't with CString?

Just a heads up, I'm referencing from a working code, and I'm trying to implement the same method but with a CString.
The below method that works, casting an integer as a void pointer:
void **pParam = new void*[2];
pParam[0] = reinterpret_cast<void*>(this);
pParam[1] = reinterpret_cast<void*>(iTrayNumber);
_beginthreadex(NULL, 0, &CInspectionDone::InspectionDoneThread, reinterpret_cast<void*>(pParam), 0, NULL);
Whereas if I do the same for CString, I'm getting these errors:
CString strTest = _T("Hello");
void **pParam = new void*[2];
pParam[0] = reinterpret_cast<void*>(this);
pParam[1] = reinterpret_cast<void*>(strTest);
errors:
1>d:\v4\apps\serialcomm.cpp(160) : error C2440: 'reinterpret_cast' : cannot convert from 'CString' to 'void *'
1> Conversion requires a constructor or user-defined-conversion operator, which can't be used by const_cast or reinterpret_cast
Is it because fundamentally you can't do the same for a CString? I tried searching around the internet and it says the function for reinterpret cast is to convert pointer of one data type to another. Unless maybe pointers are just integers and it's being accepted to be casted.
If there are any explanations on this, I'll greatly appreciate it! Thanks in advance.
reinterpret_cast performs a number of specific casts, all of which are needed only in rather special circumstances. You shouldn't need reinterpret_cast for what you are doing here.
One of the casts allowed with reinterpret_cast is casting one object pointer type to another object pointer type. The effect of this depends on the exact types. This is mostly useful when casting to char* or unsigned char* to obtain the object representation of an object.
reinterpret_cast<void*> is pointless because conversion from any (non-const/volatile) object pointer type to void* is implicit. The cast is not required at all. Even if it is required static_cast will do the same and be less risky (since most use of reinterpret_cast is likely to end with undefined behavior). This conversion doesn't change the pointer value. The void* will point to the same object as the original pointer did. You then need to later cast the void* back to the original type with a static_cast (no reinterpret_cast required either). Casting to other types will almost always end with undefined behavior.
Another conversion reinterpret_cast can perform is between object type pointers and integers. This will map the address of the pointer in some implementation-defined way to an integer value (and back). Again the only way this is useful is if you cast the integer value obtained from a pointer back to its original type. Casting a random integer value to a pointer will not likely result in a pointer value that is usable either. All of this is implementation-defined (except for the round-trip pointer->integer->pointer cast leaving the value unchanged).
However there simply is no specific conversion in the list of possible conversions for reinterpret_cast that allows casting a class type to a pointer type. So CString can't be cast to void* in this way. But there wouldn't be any meaningful way to do such a conversion anyway. What would you expect the resulting pointer value to represent?
You should not need any reintepret_cast here. A simple structure holding the properly-typed types will do:
struct Params {
CInspectionDone* a;
int b;
};
void *pParam = new Parames{this, iTrayNumber};
_beginthreadex(NULL, 0, &CInspectionDone::InspectionDoneThread, pParam, 0, NULL);
And then InspectionDoneThread can access the parameters with e.g. static_cast<Params>(arg)->a and delete the parameters with delete static_cast<Params>(arg);.
Or even better use modern C++. Since a decade ago there is std::thread, which doesn't require any pointers at all. InspectionDoneThread can just be a non-static member function with the integer as argument with appropriate type instead of needing to be a static member function with void* parameter. And then:
auto mythread = std::thread(&CInspectionDone::InspectionDoneThread, this, iTrayNumber);
or with a lambda:
auto mythread = std::thread([&]{ InspectionDoneThread(iTrayNumber); });

Misleading syntax/parser error: Expected > instead of * in reinterpret_cast

I am getting a weird syntax error when trying to reinterpret-cast a pointer:
void my_function(std::unique_ptr<float[]> ptr) {
// Some stuff
... = reinterpret_cast<uint8_t[]*>(ptr.release());
// Some other stuff
}
I'm getting the following error message:
error: expected '>'
reinterpret_cast<uint8_t[] *>(ptr.release()));
^
I have a '<' and a matching '>', so I don't understand what's causing the error. What could be the problem here?
Assuming you're either trying to serialize data, you should be casting to a regular uint8_t pointer. For this, just do:
reinterpret_cast<uint8_t*>(ptr.release());
Note that ptr.release() releases onwership of the pointer owned by the unique_ptr, and that deleting a pointer to an array of float as a pointer to an array of uint8_t is undefined behavior. Always delete a pointer as it's original type, without casting it.
I would recommend using ptr.get() instead, as this doesn't transfer ownership:
reinterpret_cast<uint8_t*>(ptr.get());
Why you got the error: The syntax for a pointer to an array is uint8_t(*)[]. It's... weird, and until another commenter pointed it out, I didn't know that it existed (it's an artifact of backwards compatibility with C).
Because of that, the compiler doesn't expect to see a * after uint8_t[], so it says that it expected the closing bracket of the reinterpret_cast.
Do you really want a pointer to an array of uint8_t, as opposed to just a pointer to uint8_t ?
If so, it is written uint8_t(*)[].
But I think what you actually want is most likely a pointer to uint8_t, i.e. uint8_t *.

Is it possible to cast one function type to another function type that takes same parameter but different return type?

I just saw one line of code
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
}
I did not quite get it,
then i looked up the function definition.
GLFWglproc glfwGetProcAddress(const char *procname)
// which means this is a function takes a pointer and returns something
that something is
typedef void(* GLFWglproc) (void)
// a function pointer
ok the glfwGetProcAddress takes a pointer and returns a function pointer
however when i looked the code (GLADloadproc) glfwGetProcAddress , what does it mean?
typedef void* (* GLADloadproc)(const char *name);
the GLADloadproc is also a function pointer.
the outter function
void gladLoadGLLoader(GLADloadproc);
is just a normal function. it takes a function pointer , do something with it and returns nothing.
ok , so , when invoking gladLoadGLLoader, the inside is a function pointer, that means (GLADloadproc)glfwGetProcAddress is a function pointer pointing to some function . it never invoked the glfwGetProcAddress,
however, when i do this
if (!gladLoadGLLoader(static_cast<GLADloadproc>(glfwGetProcAddress))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
main.cpp:46:27: error: static_cast from 'GLFWglproc (*)(const char *)' (aka
'void (*(*)(const char *))()') to 'GLADloadproc' (aka 'void *(*)(const
char *)') is not allowed
where am i wrong?
where am i wrong?
You used the wrong cast for the job. A static_cast is very strict in its static type checking. The two pointer types are unrelated, so a static cast would be ill-formed.
What you may use to cast function pointer types is a reinterpret_cast. Beware however, that short of a C-style cast (which will try to guarantee some cast is performed), a reinterpret cast is a very blunt tool. Don't use it unless you really need it, because it forgoes a lot of static type checking.
Finally, only use the resulting pointer type to call the function if you know for sure that it matches the functions declared prototype. Otherwise you'd get undefined behavior.

How can I cast a pointer of type size_t to a pointer of enum ?

I want to assign a size_t to this container :
std::vector <nts::Tristate *> _components;
To do so, I am trying to cast const size_t & to nts::Tristate *
this->_components[0] = static_cast<nts::Tristate *>(&value);
But I have the following error :
error: invalid static_cast from type ‘const size_t* {aka const long unsigned int*}’ to type ‘nts::Tristate*’
this->_components[0] = static_cast<nts::Tristate *>(&value);
Have any idea why ?
Without asking why you want to do something like that, the problem is that the two types (size_t* and nts::Tristate*) are completely unrelated, and you need to reinterpet one type as the other. You do thing with reinterpret_cast.
It should be noted that doing something like this will most likely lead to other problems down the road, problems that will lead to undefined behavior. One of the things you need to watch out for is if value is a local variable, because then you store a pointer to this local variable that will go out of scope and disappear. Another is that the rest of the program that uses _components[0] needs to know that it's not actually a pointer to a nts::Tristate object but a pointer to a size_t value. In short, what you're doing is very dangerous.

invalid conversion from 'const void*' to 'PVOID {aka void*}' [-fpermissive]

I am writing a program (well... using sample code form Tektronix) to test the message exchange over the network to our spectrum analyser in our lab.
A header file called "decl-32.h" has been provided, and in the sample code is the following line, along with the error it produces:
ibwrt(GpibDevice, "SYSTem:ERRor:ALL?", strlen("SYSTem:ERRor:ALL?"));
"invalid conversion from 'const void*' to 'PVOID {aka void*}' [-fpermissive]"
Within the header file, the following line of code is highlighted as erroneous, along with the following error:
extern int __stdcall ibwrt (int ud, PVOID buf, long cnt);
"initializing argument 2 of 'int ibwrt(int, PVOID, long int)' [-fpermissive]"
The problem is that I am unfamiliar with such complex variable definitions, uses and conversions.
Could somebody be kind enough to offer me some advice? I'm sure this would be relevant to many others who are unfamiliar with such variable types and conversions, etc.
Thank you in advance!
The second parameter to ibwrt is PVOID which is a typedef for void*. In C++, pointer types are implicitly convertible to void*, but, as with all other types, the conversion is not allowed to drop a qulifier. That is, conversion from const char* (which is the type string literals decay to) to void* is illegal. Hence the error.
In C language, which is where the code is coming from, string literals decay to char* and your line will compile as is. The reason is historical - early implementations of C didn't have const keyword.
To fix it, you can cast the const away with a const_cast:
const char* s = "SYSTem:ERRor:ALL?";
ibwrt(GpibDevice, const_cast<char*>(s), strlen("SYSTem:ERRor:ALL?"));
You need to trust the function that it'll not attempt to modify the string literal through the pointer you passed it, otherwise it would invoke undefined behaviour. Seems like a safe assumption in this case (or maybe not, the parameter is named buf, mind you!), but if you want to be sure, do a copy of the string like #MikeSeymour shows in his answer.
The problem is that string literals are immutable, and this function requires a non-const pointer to the data.
If the function is guaranteed not to modify the data, and the lack of const is just an oversight, then you can cast to the required type:
ibwrt(GpibDevice, const_cast<char*>("SYSTem:ERRor:ALL?"), strlen("SYSTem:ERRor:ALL?"));
If it might modify the data, then this will give undefined behaviour, and you'll need a local copy of the string:
const char message[] = "SYSTem:ERRor:ALL?";
ibwrt(GpibDevice, message, strlen(message));
(You could specify the length as the less obvious but perhaps more efficient sizeof message - 1)