Указатель пользователя Ncurses

Я пытаюсь изучить ncurses и читаю потрясающее руководство здесь , но пример с указатели пользователей не компилируется. Я получаю эту ошибку, когда пытаюсь скомпилировать.

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*)'

Кроме того, вам, вероятно, потребуется добавить cstdlib и cstring для компиляции с помощью strlen и calloc.

Я не очень разбираюсь в указателях void, поэтому буду очень признателен за помощь в исправлении примера.

Спасибо


person Reti    schedule 09.02.2010    source источник


Ответы (2)


Из чтения страницы руководства:

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

ОПИСАНИЕ

У каждого пункта меню есть поле, которое можно использовать для хранения данных, специфичных для приложения (то есть код драйвера меню оставляет его в покое). Эти функции получают и устанавливают это поле.

userptr — это пользовательские данные, которые вы должны предоставить set_item_userptr(). Если вы не хотите предоставлять какие-либо данные, вы должны указать NULL. Похоже, вы вызываете set_item_userptr() с указателем на функцию в качестве второго аргумента. Не гарантируется, что вы сможете преобразовать указатель на функцию в void * и обратно переносимым образом как в C, так и в C++ (C++ требует приведения при преобразовании void * в любой другой тип указателя). Не зная, что вы пытаетесь сделать, если вам действительно нужно передать указатель на функцию, вы должны привести его к соответствующему типу:

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

но это не гарантирует работу. Вы должны сделать что-то еще, например иметь struct, который содержит указатель на функцию, и передать указатель на struct в set_item_userptr().

person Alok Singhal    schedule 09.02.2010
comment
То, что я пытаюсь сделать, это создать меню, которое будет выполнять некоторую функцию, когда я нажимаю Enter при выборе. - person Reti; 09.02.2010
comment
@Reti: я не знаю проклятий, но я предполагаю, что должен быть лучший способ сделать то, что вы хотите сделать, чем привести указатель функции к void *. - person Alok Singhal; 09.02.2010

Вы используете компилятор С++, поэтому вам нужно будет сделать:

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

и опять,

    p = (void*)item_userptr(cur);
person dirkgently    schedule 09.02.2010
comment
Два комментария. 1 - Я бы рекомендовал reinterpret_cast‹› как лучший стиль, чем приведения в стиле C. 2 - строка 70 является обратным приведением, поэтому приведение должно быть p = reinterpret_cast<void (*)(char *)>(item_userptr(cur)); - person R Samuel Klatchko; 09.02.2010
comment
Почему reinterpret_cast, если static_cast в void* и обратно нормально? - person Georg Fritzsche; 09.02.2010
comment
@gf - static_cast не будет преобразовывать между void * и void (*)(char *). Попытка static_cast на g++ 4.2.1 дает invalid static_cast from type ‘void*’ to type ‘void (*)(char*)’. - person R Samuel Klatchko; 09.02.2010
comment
@*На самом деле, я предпочитаю приведения в стиле C — пусть компилятор выбирает наиболее подходящий — в таких случаях (более reinterpret_casts). - person dirkgently; 09.02.2010
comment
@R Samuel: Ах, я не знал, что обработка указателей на функции отличается. - person Georg Fritzsche; 09.02.2010