views:

99

answers:

2

I'm trying to learn ncurses, and I'm reading the terrific guide here, but the example at user pointers does not compile. I get this error when I try to compile.

menu.cpp: In function 'int main()':

menu.cpp:44: error: invalid conversion from 'void (*)(char*)' to 'void*'

menu.cpp:44: error: initializing argument 2 of 'int set_item_userptr(ITEM*, void*)'

menu.cpp:70: error: invalid conversion from 'void*' to 'void (*)(char*)'

Also, you probably need to add cstdlib and cstring for that to compile with strlen and calloc.

I don't know much about void pointers, so some help fixing the example would be very appreciated.

Thanks

+1  A: 

You are using a C++ compiler, so you will need to do:

    set_item_userptr(my_items[i], (void *)func);

and again,

    p = (void*)item_userptr(cur);
dirkgently
What about the error on line 70?
Reti
Two comments. 1 - I'd recommend reinterpret_cast<> as better style then C style casts. 2 - line 70 is the reverse cast so the cast should be `p = reinterpret_cast<void (*)(char *)>(item_userptr(cur));`
R Samuel Klatchko
Why `reinterpret_cast` if `static_cast` to `void*` and back is fine?
Georg Fritzsche
@gf - static_cast will not convert between `void *` and `void (*)(char *)`. Trying static_cast on g++ 4.2.1 gives `invalid static_cast from type ‘void*’ to type ‘void (*)(char*)’`.
R Samuel Klatchko
@*Actually, I prefer the C-style casts -- let the compiler choose the best fit -- in such cases (over `reinterpret_cast`s).
dirkgently
@R Samuel: Ah, i didn't know that the handling was different for function pointers.
Georg Fritzsche
+2  A: 

From reading the manual page:

#include <menu.h>
int set_item_userptr(ITEM *item, void *userptr);
void *item_userptr(const ITEM *item);

DESCRIPTION

Every menu item has a field that can be used to hold application-specific data (that is, the menu-driver code leaves it alone). These functions get and set that field.

userptr is user-specific data that you should supply to set_item_userptr(). If you don't want to supply any data, you should supply NULL. Looks like you are calling set_item_userptr() with a pointer to a function as its second argument. It is not guaranteed that you can convert a function-pointer to void * and back portably, either in C or in C++ (C++ requires a cast when converting a void * to any other pointer type). Without knowing what you are trying to do, if you really need to pass a function pointer, you should cast it to the appropriate type:

int ret = set_item_userptr(item, reinterpret_cast<void *>(ptr));
void (*pf)(char*);
pf = reinterpret_cast<void (*)(char *)>(item_userptr(item));

but it's not guaranteed to work. You should do something else, like having a struct that contains the function pointer, and passing a pointer to the struct to set_item_userptr().

Alok
What I'm trying to do is make a menu that will execute some function when I hit enter on the selection.
Reti
@Reti: I don't know curses, but I am guessing there should be a better way of doing what you want to do than to cast a function pointer to `void *`.
Alok