什么是void * userData究竟是什么?

时间:2010-05-01 12:51:03

标签: c

在C函数声明中,我看到了这个参数定义:

void *userData

那么,究竟是什么?我的猜测:虚空说它可以是任意的,甚至一无所有。几乎与objective-c的id相似。它只允许传入你喜欢的任何数据结构。

userData前面的星号表示必须通过引用传递参数。

因此,当在函数体中使用这些东西时,通常必须对其进行转换和取消引用。 因此,如果我传入指向SomeClass实例的指针,我会这样做:

SomeClass *myObj = (SomeClass*)userData;

在我没有特别传递的情况下,我会提供NULL作为参数。

我的假设是否正确?或者我弄错了什么?

5 个答案:

答案 0 :(得分:4)

void *是指向未知类型结构的指针。你可以把它想象成“指向任何东西的指针”。它的与Objective-C的id类型相同,它是任何对象的类型。 ID如下所示:

typedef struct objc_object {
  Class isa;
} *id;

通常在Objective-C中(我也确定在C中),框架可能会使用一些回调来告诉你一些事情。该回调通常会采用包含您提供的数据的参数 - 也许是启动操作的对象,并且需要知道发生了什么。 void *参数允许框架定义回调而不依赖于您的代码,因此您可以将任何您喜欢的内容放入回调中。 (当然,这意味着您还必须确保将void *userData转换回适当的类型。)

答案 1 :(得分:3)

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;)"
}

答案 2 :(得分:3)

void *是指向任何数据类型的指针。

请注意,一定是指向函数的指针的正确大小。

答案 3 :(得分:1)

没有看到实际代码我猜测参数属于一个需要回调的函数?如果是这样,它可能是一个上下文,正如你所说,你可以设置任何你想要的。当函数调用您的回调时,它将传递此上下文,这意味着您不需要全局来存储此数据。

答案 4 :(得分:0)

你的理解基本上是正确的,虽然它被称为指针而不是引用。这通常是一种让用户通过传入任何类型的数据块来“扩展”数据结构的机制。我看到的一个例子是用于GUI中树形显示的节点。 GUI框架添加了void指针,以便当用户单击此树的节点时,您可以将有关节点的更有意义的信息提取到调用例程中,而不仅仅是其名称。由于只有您知道哪种类型的数据对您的应用程序有意义,因此类型只是一个空*。

另请注意,您几乎总是负责管理userData的内存。