Что такое void * userData? - PullRequest
2 голосов
/ 01 мая 2010

В объявлении функции C я видел определение этого параметра:

void *userData

итак, что это такое? Мое предположение: пустота говорит, что это может быть что угодно, или даже ничего. Почти похоже на id цели-c. Он просто позволяет передавать любую структуру данных, которую вы любите.

Звезда перед userData говорит, что аргумент должен быть передан по ссылке.

Таким образом, при использовании этого элемента в теле функции, как правило, он должен быть приведен и разыменован. Поэтому, если я передам указатель на экземпляр SomeClass, я получу это так:

SomeClass *myObj = (SomeClass*)userData;

В случае, если у меня не было ничего особенного, я бы указал NULL в качестве аргумента.

Верны ли мои предположения? Или я что-то не так понял?

Ответы [ 5 ]

4 голосов
/ 01 мая 2010

A void * - указатель на структуру неизвестного типа. Вы можете думать об этом как о «указателе на что-либо». Это не то же самое, что и тип идентификатора Objective-C, который является типом любого объекта. Идентификатор выглядит так:

typedef struct objc_object {
  Class isa;
} *id;

Как правило, в Objective-C (и я уверен, что в C тоже) фреймворк может использовать некоторый обратный вызов, чтобы сказать вам кое-что. Этот обратный вызов часто принимает параметр, содержащий данные, которые вы ему предоставляете - возможно, объект, который начал действие, и который должен знать, что что-то произошло. Параметр void * позволяет каркасу определять обратный вызов, не завися от вашего кода, так что вы можете помещать в него все что угодно. (Конечно, это означает, что вы также должны убедиться, что вы вернули свой void *userData обратно в соответствующий тип.)

3 голосов
/ 01 мая 2010

void * - указатель на любой тип данных .

Обратите внимание, что это , а не , обязательно правильный размер для указателя на функцию.

3 голосов
/ 01 мая 2010

void * означает указатель на что-либо. Таким образом, вы можете передать что-нибудь «по ссылке» через void * аргумент. userData имя параметра предполагает (но это всего лишь предложение, поэтому оно может варьироваться в зависимости от различных API), что этот аргумент представляет собой произвольные данные, предоставленные пользователем. То есть рассматриваемая функция ничего с этим не сделает, просто сохранит и вернет вам время. Например, в GTK + вы можете прикрепить обратный вызов к некоторому событию. Вы можете передать свои собственные данные в g_signal_connect в качестве аргумента user_data, а в обработчике событий GTK + вернет вам ваши данные:

GtkWidget *button = gtk_button_new ();
const char *data = "Hello World;)";
g_signal_connect (button, "clicked", on_clicked, data);
(...)
void on_clicked (GtkWidget *widget, void * data)
{
    const char *text = (const char *)data;
    printf ("%s\n", text); // will print "Hello World;)"
}
1 голос
/ 01 мая 2010

Не видя фактического кода, я предполагаю, что параметр принадлежит функции, которая принимает обратный вызов? Если это так, то это, вероятно, фрагмент контекста, который, как вы говорите, вы можете установить на то, что хотите. Когда функция вызывает ваш обратный вызов, она передает этот контекст, что означает, что вам не нужно глобальное хранилище для этих данных.

0 голосов
/ 01 мая 2010

Ваше понимание по существу верно, хотя оно называется указателем, а не ссылкой. Обычно это механизм, позволяющий пользователям «расширять» структуру данных путем передачи блока данных любого типа. Пример, который я видел, используется для узлов отображения дерева в графическом интерфейсе. Каркас GUI добавляет указатель void, так что когда пользователь щелкает узел этого дерева, вы можете извлечь более значимую информацию об узле, чем просто его имя, в вашу вызывающую подпрограмму. Поскольку только вы знаете, какой тип данных будет иметь значение для вашего приложения, этот тип является просто пустым *.

Также обратите внимание, что вы почти всегда отвечаете за управление памятью для пользовательских данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...