Void ** Путаница для обратных вызовов - PullRequest
0 голосов
/ 02 декабря 2011

Я работаю с инструментом отображения с открытым исходным кодом, и у него есть возможность использовать g_io_add_watch для просмотра файловых дескрипторов. Я пытаюсь посмотреть дескриптор файла stdin, и я успешно смог вызвать обратный вызов, когда stdin получает данные. Однако я не могу прочитать эти данные. Я пытаюсь изменить обратный вызов, чтобы получить информацию, описанную в обработчике для API с открытым исходным кодом.

РЕДАКТИРОВАТЬ ** Мой вопрос в первую очередь о том, что такое пустота ** и как это будет использоваться в этом случае. Я хочу, чтобы моей функции обратного вызова были предоставлены параметры, описанные для функции readUserInput_two, которую вы видите ниже, и мне нужно передать ее через систему обратного вызова, описанную ниже. Я запутался в том, что мне нужно передать как void **, чтобы позволить текущей реализации передать эти параметры.

Это выглядит так

readUserInput_two(GIOChannel *ioch, GIOCondition cond, gpointer data)

Я хочу сохранить этот указатель в обратном вызове, который определен как

struct callback {
    void (*func)();
    int pcount;
    enum attr_type type;
    void *p[0];

};

В функции, которая используется для создания обратного вызова, вы предоставляете следующие параметры

callback_new(void (*func)(void), int pcount, void **p)

В этом вызове pcount - это число параметров, которое должен иметь указатель на вашу функцию, и я считаю, void ** p - это либо тип этих параметров, либо что-то в этом роде, но я не могу понять это.

Когда вызывается обратный вызов, он вызывает функцию, определенную в операторе define, которая выглядит так.

#define callback_call_3(cb,p1,p2,p3) callback_call_args(cb, 3, p1, p2, p3)

Эта функция определена для различных чисел р. callback_call_1 (cb, p1) также существует. Может кто-нибудь объяснить, как я мог бы получить мою функцию обратного вызова для получения этих полей данных. промежуточная функция вызова обратного вызова, которая вызывает callback_call_3, выглядит следующим образом.

static gboolean
navfocus_call_watch(GIOChannel * iochan, GIOCondition condition, gpointer t)
{
    struct callback *cb=t;
    if(cb->pcount == 1)//I added this if before it only had callback_call_0
    {
        callback_call_0(cb);
    }
    else if(cb->pcount == 4)
    {
        callback_call_3(cb,iochan,condition,t);
    }
    return TRUE;
}

Ответы [ 2 ]

2 голосов
/ 03 декабря 2011

void ** - указатель на указатель данных типа void (без типа). void * используется в качестве универсального типа для указания на базовый адрес любой переменной типа. В этом случае void ** ожидает хранения нескольких переменных void *. Вы можете назвать его как массив void.

Существуют различные функции, которые должны быть вызваны на основе количества параметров, отправленных из callback_new (). Для удобства написаны макросы.

Вам нужно вставить эти параметры в void ** p. Вы можете выделить память для массива void ** p следующим образом:

void **p = malloc(10 * sizeof *p);

Вам необходимо вставить их в том же порядке, который требуется для последней вызываемой функции.

Скажи для трех параметров функции:

p[0] = &iochan;
p[1] = &condition;
p[2] = &t;

Теперь отправьте void ** p в callback_new (theFunctionPointer, 3, p); и, как вы объяснили, соответствующая функция будет вызываться в зависимости от количества параметров.

1 голос
/ 02 декабря 2011

A void** - это тип для указателя на указатель на void.

Что касается того, как использовать его в вашем случае, вам придется ознакомиться с документацией. Я не могу сказать по фрагменту кода, который вы разместили, и имя переменной "p" тоже не очень помогает.

Редактировать: Что касается вашего обратного вызова с предоставлением исходных данных, функция обратного вызова не имеет аргументов. Как функция получает ваш указатель?

Edit2: я вижу, это связано с pcount. Но тогда объявление обратного вызова неверно, поскольку в нем говорится, что обратный вызов не принимает никаких аргументов ...

...