什么是void * userData到底是什么?

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

void *userData 

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

userData前面的星标表示,参数必须通过引用传入。

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

 SomeClass *myObj = (SomeClass*)userData; 

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

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

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

 typedef struct objc_object { Class isa; } *id; 

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

void *表示指向任何东西的指针。 所以,你可以通过void *参数“通过引用”传递任何东西。 userData参数名称建议(但只是一个建议,因此它可能会因各种API而异),此参数是一些任意用户提供的数据。 也就是说,有问题的function对它没有任何作用,只是存储,并在一段时间内将它还给你。 例如,在GTK +中,您可以将回调附加到某个事件。 您可以将自己的数据作为user_data参数传递给g_signal_connect ,在事件处理程序中,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;)" } 

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

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

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

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

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