I have another problem regarding pointers.
I have a function with the following header:
addActor (NxuPhysicsCollection &c, NxActor &a, const char *userProperties=0, const char *actorId=0)
And I am trying to use it like this:
NXU::NxuPhysicsCollection* collection = new NXU::NxuPhysicsCollection();
NxActor* actor = *actors++;
NXU::addActor(collection, actor, NULL, NULL);
But I get the following error:
A reference of type "NXU::NxuPhysicsCollection&" (not const-qualified) cannot be initialised with a value of type "NXU::NxuPhysicsCollection*" (this is for the collection parameter, same error appears for actor as well)
How am I supposed to pass the collection and actor parameters to the function in order to work properly?
I tried this:
NXU::addActor(&collection, &actor, NULL, NULL);
But that doesn''t work either, it gives me the error:
"Initial value of reference to non-const must be a lvalue."
Any help is greatly appreciated.
Edit: If I use it like this:
NXU::addActor((NXU::NxuPhysicsCollection&)collection, (NxActor&)actor, NULL, NULL);
It does not give me errors anymore. Is this correct?
I must mention that NXU and NX namespaces are closed source and I cannot modify the way they are implemented
Since the formal arguments of your member function for c and a are references, while collection and actor are pointers, you need to dereference pointers to make them compatible with references:
// No need to pass NULLs for the defaulted parameters, so
// the trailing NULL, NULL are removed.
NXU::addActor(*collection, *actor);
Alternatively, you can change the signature of the constructor to accept pointers instead of references:
addActor (NxuPhysicsCollection *c, NxActor *a, const char *userProperties=0, const char *actorId=0)
// ^ ^
// | |
// Here and Here
Both the c and a parameters are references.
Pass them as:
NXU::addActor(*collection, *actor, NULL, NULL);
This act is called pointer-dereference.
NXU::addActor(*collection, *actor, NULL, NULL);
because
addActor (NxuPhysicsCollection &c, NxActor &a, const char *userProperties=0, const char *actorId=0)
receives collection and actor by reference, not by pointer
Related
FILE *LCD_stdout = new FILE();
int (*ptr)(char, FILE *) = ROBOT::__LCD_putchar;
fdev_setup_stream(LCD_stdout, ptr, NULL, _FDEV_SETUP_WRITE );
stdout = LCD_stdout;
gives me error:
In member function 'SUBSYS_OPENSTAT ROBOT::LCD_open()':
LCD.cpp:108: error: argument of type 'int (ROBOT::)(char, __file*)' does not match 'int (*)(char, __file*)'
I've looked at a number of solutions through Stack Overflow and whatnot. .* doesn't resolve it, tried assigning a pointer of a pointer, and I feel I'm likely not going to be resolve it without resolving misconceptions.
The compiler error tells you exactly what's wrong:
argument of type 'int (ROBOT::)(char, __file*)' does not match 'int (*)(char, __file*)
...because pointers to member functions aren't compatible with pointers to non-member functions, for a couple of reasons.
One option is to create a separate free function but this depends on where the ROBOT object resides. For example if you have a global ROBOT object you could do the following
ROBOT globalRobot;
int callback(char c, FILE* f)
{
return globalRobot.__LCD_putchar(c, f);
}
FILE *LCD_stdout = new FILE();
fdev_setup_stream(LCD_stdout, callback, NULL, _FDEV_SETUP_WRITE );
stdout = LCD_stdout;
If there is only going to be one robot object and it is a member variable of another class change globalRobot to be a pointer and set it after the ROBOT object has been created (ROBOT's constructor maybe)
This is untested as I don't know the innards of ROBOT but everything looks ok.
I'm developing for an embedded hardware using C++ and I often use pointers to const (ROM) structs to minimize the object sizes.
When I get a pointer passed to my class constructor, I want the compiler to create another ROM object based on the one I passed but with one or two arguments changed and just then call the parent class constructor (Display_Element). Any ideas of how this could be done?
Since a const string can be declared within a parameter list I though possibly there could be a way of also declaring a const struct within a parameter list.
I wanted to do something like this, (which is illegal in C++)
Button::Button(const Colors_const* ecc, const Display_element_const* edc, const Element_const* eec, char* elabel,
Display_element* eparent, Screen* escreen) :
Display_element(ecc, cc,Display_element_const {
edc->xi+200,
edc->xf,
edc->yi,
edc->yf,
edc->font_size,
edc->image,
edc->image_x_offset,
edc->image_y_offset,
edc->label_x_offset,
edc->label_y_offset,
edc->mouse_down_ptr,
NULL,
edc->largura_borda_externa,
edc->borda_panel
},
eec,elabel,eparent,escreen) {
flags.largura_borda = 2;
//flags.largura_borda_externa = 3;
flags.borda_light_shadow = true;
flags.sliding_text = true;
flags.dont_paint_on_click = false;
}
Thanks
Well, it seems what I want to do is really illegal and can't be done in C. But philosophically I keep asking myself: if I can allocate a const char[n] written inside a parameter list such as fn(...,"The brow dog",...) why not a way to allocate a const struct the same way? If someone knows the answer, please post!
The workaround I found is to do it the canonical way: declare a const struct and then later assign the appropriate pointer to the struct (something I wanted to be done inside Display_element function on the first place). It solves my problem, but not the conceptual question I've been trying to formulate...
const Display_element_const new_ec = {
edc->xi+200,
edc->xf,
edc->yi,
edc->yf,
edc->font_size,
edc->image,
edc->image_x_offset,
edc->image_y_offset,
edc->label_x_offset,
edc->label_y_offset,
edc->mouse_down_ptr,
NULL,
edc->largura_borda_externa,
edc->borda_panel
};
Button::Button(const Colors_const* ecc, const Display_element_const* new_edc, const Element_const* eec, char* elabel,
Display_element* eparent, Screen* escreen) :
Display_element(ecc, edc,eec,elabel,eparent,escreen) {
//previously dc = edc, assigned inside Display_element fn
dc = &new_ec;
I have a class called CSum which contains a static method who's identifier is:
static double fileProc(string myFile);
In my main function I would simply call it by
CSum::fileproc("foo.txt")
However, I will like to invoke pthreads on two separate files. Therefore I need to obtain the address of this method. I do so by
return1 = pthread_create(&t1, NULL, &CSum::fileProc(file1), NULL);
return2 = pthread_create(&t2, NULL, &CSum::fileProc(file2), NULL);
But I get an error
lvalue required as a unary '&' operand.
Any suggestions?
You don't pass parameters, you just give the name of the function. The parameter you want it to get is the next parameter of the pthread_create.
Instead of
pthread_create(&t2, NULL, &CSum::fileProc(file2), NULL);
do
pthread_create(&t2, NULL, &CSum::fileProc, file2);
Cast types as appropriate. Note that the thread function is supposed to accept a pointer as a parameter, make sure you define it appropriately.
CSum::fileProc(file1) is an expression that calls the function and gives you the value the function returns as the value of the expression. You are trying to take the address of that value, which you can't, and this won't do what you want.
&CSum::fileProc will give you the function pointer, but it does not have the correct signature for use with pthreads. Since pthreads is a C library, it has a very simplistic interface. Your best bet for C++ is to use a higher-level C++ library that uses pthreads underneath (at least on unixes), like boost threads.
If for some reason yoou can't do that, you need to write your own wrappers. To call your function in a separate thread, you would need to write something like:
class CSum {
...
static void fileProcWrapper(void* param) {
const char* fileName = (const char*) param;
fileProc(fileName);
}
...
and call it with
pthread_create((&t2, NULL, &CSum::fileProc, (void*) file1.c_str());
That just gives you the call, mind, the result is thrown away with this code. If you want to collect the result with pthread_join, you have to do a bit more work.
Am struggling a bit with this.
Am declaring:
BYTE *pImage = NULL;
Used in call:
m_pMyInterface->GetImage(i, &imageSize, &pImage);
Visual C++ 2003 compiler error:
error C2664: 'CJrvdInterface::GetImage' : cannot convert parameter 3 from 'BYTE **__w64 ' to 'BYTE **& '
A reference that is not to 'const' cannot be bound to a non-lvalue
The method called is defined as:
void CMyInterface::GetImage(const int &a_iTileId, ULONG *a_pulImageSize,
BYTE** &a_ppbImage)
Any help much appreciated,
Bert
Because GetImage can modify it's third parameter, you need to give it something to modify:
BYTE **ppImage = &pImage;
m_pMyInterface->GetImage(i, &imageSize, ppImage);
It is possible that after your function returns, that &pImage and ppImage may no longer be the same (which also means that pImage and *ppImage may be different). If you add this:
if (ppImage)
pImage = *ppImage;
after the call, you should be good.
If CMyInterface::GetImage is your own function, depending on what you do, you may be able to change it. In your function, do you ever do:
a_ppbImage = ...;
or do you only write:
*a_ppbImage = ...;
If you only do that latter and not the former, passing a reference to a double pointer is overkill. You can either pass a reference to a single pointer (BYTE *&image) or you can pass a double pointer (BYTE **image)
If you are trying to modify the variable 'pImage' inside the method 'GetImage()' you should either be passing a pointer or a reference to it (not doing both).
What you probably want is:
BYTE *pImage = NULL;
x.GetImage(iTileId, pulImageSize, a_pImage );
With the method defined as:
void CMyInterface::GetImage(int const& a_iTileId, ULONG* a_pulImageSize, BYTE*& a_ppbImage)
{
}
PS. Be consistent where you put your & and * in type declarations.
ULONG *a_pulImageSize // Star on the right
BYTE** &a_ppbImage // Star on the left (not consistent)
Personally (and this is just my style others are different) I put everything on the left (with the type) just the variable name goes on the right.
You declared GetImage() to expect a reference to a Byte**.
void CMyInterface::GetImage(const int &a_iTileId,
ULONG *a_pulImageSize,
BYTE** &a_ppbImage);
You passed it a reference to a Byte*.
BYTE *pImage = NULL;
m_pMyInterface->GetImage(i, &imageSize, &pImage);
To make your method call work as written, you need to change your definition of GetImage() to
void CMyInterface::GetImage(const int &a_iTileId, ULONG *a_pulImageSize,
BYTE* &a_ppbImage)
Using C++.
pthread_t threads[STORAGE]; // 0-99
...
void run()
Error>>> int status = pthread_create(&threads[0], NULL, updateMessages, (void *) NULL);
if (status != 0)
{
printf("pthread_create returned error code %d\n", status);
exit(-1);
}
...
void ClientHandler::updateMessages(void *)
{
string reqUpdate = "91"; // Request for update
string recvMSG;
while (true)
{
sleep(5);
sending(sock,reqUpdate); // send
recvMSG = receiving(sock); // receive
QString output(recvMSG);
emit signal_chat(output, 0); // Print message to text box
}
}
...
Compile Error:
TCPClient.cpp:109: error: argument of type ‘void (ClientHandler::)(void*)’ does not match ‘void* (*)(void*)’
I can't figure out whats wrong.
Thanks in advance.
A pointer to a member function is different from a global function with the same signature since the member function needs an additional object on which it operates. Therefore pointers to these two types of functions are not compatible.
In this case this means that you cannot pass a member function pointer to pthread_create but only a pointer to a non-member (or static) function. A work around for this problem is to use the forth parameter of pthread_create to pass a pointer to a object to a global function which then calls the method of the passed object:
class ClientHandler {
public:
void updateMessages();
void run();
};
// Global function that will be the threads main function.
// It expects a pointer to a ClientHandler object.
extern "C"
void *CH_updateMessages(void *ch) {
// Call "real" main function
reinterpret_cast<ClientHandler*>(ch)->updateMessages();
return 0;
}
void ClientHandler::run() {
// Start thread and pass pointer to the current object
int status = pthread_create(&threads[0], NULL, CH_updateMessages, (void*)this);
...
}
It's nothing to do with threads, it's a normal C++ error, you're just passing an incompatible type of function pointer.
A function pointer is not the same as a member instance function pointer, even if their signature is the same; this is because there is an implicit reference to *this passed. You can't avoid this.
As pthread_create takes a free function, create a static function(is a free function) inside ClientHandler
static void Callback(void * this_pointer,int other_arg) {
ClientHandler* self = static_cast< ClientHandler*>(this_pointer);
self-> updateMessages(other_arg);
}
and call pthread_create as follows
pthread_create(&threads[0], NULL, &ClientHandler::Callback, (void *) pointer_to_ClientHandler,int other_arg);
That works because Callback is free function
YoLinux has a nice pthread tutorial that my help you in learning about threads.
As others have already said, the problem is that the signatures between the functions are different. Class member functions always have a "secret" extra parameter, the this pointer. So you can never pass a member function where a global function is expected. You can hack around this either with libraries such as Boost.Bind, or by making the function a static member of the class.
But the simplest, and most elegant solution is to use a different threading API.
Boost.Thread is a very nice threading library for C++ (pthreads is designed for C, and that's why it doesnt play well with C++ features such as class methods).
I'd recommend using that.
Your code could be rewritten as something like this:
class ClientHandler {
public:
ClientHandler(/* All the parameters you want to pass to the thread. Unlike pthreads you have complete type safety and can pass as many parameters to this constructor as you like */){...}
void operator()() // boost.thread calls operator() to run the thread, with no parameters. (Since all parameters were passed in the constructor and saved as member variables
{
string reqUpdate = "91"; // Request for update
string recvMSG;
while (true)
{
sleep(5);
sending(sock,reqUpdate); // send
recvMSG = receiving(sock); // receive
QString output(recvMSG);
emit signal_chat(output, 0); // Print message to text box
}
}
// whatever arguments you want to pass to the thread can be stored here as member variables
};
boost::threead_group gr; // can store all your threads here, rather than being limited to your fixed-size array
gr.create_thread(ClientHandler(/* construct a ClientHandler object with the parameters you like*/));
You're passing a member function instead of a global, normal, one.
Just define:
void updateMessages(void *) {
static ClientHandler c;
// use c..
}