繁体   English   中英

C编程:void *参数是它真正指向任何东西,我可以在那里传递函数指针

[英]C programming: void * argument is it really pointer to anything, can I pass function pointer there

我考虑如何正确使用void * (我从C语言中有一些突破)。 我记得void *用于启用任何参数传递给回调函数。 我知道将原始类型int * ,const char *或甚至值集合作为struct attributes *传递是可以的。

我考虑将指向函数的指针传递给void *是否正常。

恩。

typedef void (*callback_t)(void *);
typedef void (*my_custom_callback_t)( /* list of params */ )

void someAPIFunction( /*... */, callback_t callback, void *callback_param);

void standard_callback(void *param) { 

       ((my_custom_callback_t) param) ( /* my params */ );
}

我考虑是否有这样的类型将my_custom_callback作为param传递给standard_callback是正确的吗?

void my_custom_callback(/* list of params */) { }

someAPIFunction( /*...*/, standard_callback, my_custom_callback); 

不,你不能将函数指针作为void *传递。

6.3.2.3指针

  1. 指向void的指针可以转换为指向任何对象类型的指针。 指向任何对象类型的指针可以转换为指向void的指针,然后再返回; 结果应该等于原始指针。

  1. 指向一种类型的函数的指针可以被转换为指向另一种类型的函数的指针并且再次返回; 结果应该等于原始指针。 如果转换的指针用于调用类型与引用类型不兼容的函数,则行为未定义。

注意没有提到混合对象和函数指针的可能性。 它可能似乎适用于某些系统,但它是未定义的行为,并不能保证工作。

但是,您可以创建包装器对象并传递该地址:

struct wrapper {
    my_custom_callback_t func;
};

struct wrapper my_wrapper = { my_custom_callback };
someAPIFunction( /*...*/, standard_callback, &my_wrapper); 

或者只是将指针传递给函数指针(函数指针变量是对象类型):

my_custom_callback_t func = my_custom_callback;
someAPIFunction( /*...*/, standard_callback, &func); 

事实上,大多数平台都允许您将函数指针作为void *传递,但理论上不允许这样做。 代码可能有不同的数据指针。 您也无法将const限定地址传递给void *。

正如已经指出的那样,在一般情况下不允许这样做,您可能会收到编译器警告。 这是因为存在函数指针大于数据指针的平台。

然而,更常见的情况是指针大小确实相等。 用于访问共享对象的接口dlsym()dlsym()GetProcAddress()实际上依赖GetProcAddress()

因此,如果您确定所有目标平台将使用与数据指针相同的函数指针大小,则可以通过首先转换为例如uintptr_t使其显式化(因此编译器不会发出任何警告)。 所有指针类型都允许使用整数转换, 只要整数足够大以容纳指针 ,定义良好。 uintptr_t保证足够大以容纳数据指针,因此如果函数指针的大小相同,那就没问题了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM