简体   繁体   English

C:如何访问存储在void指针(void *)中的函数指针?

[英]C: How to access a function pointer stored in a void pointer (void *)?

Confused as to how one can access a function pointer stored in a void pointer (void *). 关于如何访问存储在void指针(void *)中的函数指针感到困惑。


Let's say you have this: 假设您有以下内容:

void *functions[] =
{
    &sqrt,         // int ft_sqrt(int nb);
    &power,
    &logN,
    &factorial;
};

// An array of void pointers, each storing a function pointer.

If I wanted to access the sqrt function, my guess would be the following: 如果我想访问sqrt函数,我的猜测将是:

(int (*)(int)) functions[0](x)

But my guess is wrong: 但是我的猜测是错误的:

error: called object type 'void *' is not a function or function pointer


So how would one access one of these functions ? 那么,一个人将如何访问这些功能之一?

Strictly speaking, you can't. 严格来说,你不能。 A conversion between a function pointer and a void pointer is not possible. 函数指针和void指针之间的转换是不可能的。 void* was never a generic pointer type for function pointers, only for object pointers. void*从来不是函数指针的通用指针类型,仅是对象指针。 They are not compatible types. 它们不是兼容类型。

In practice, any pointer will very likely have the size required by the address bus of the system, so object pointers and function pointers will very likely have the same representation. 实际上,任何指针很可能具有系统地址总线所需的大小,因此对象指针和函数指针将很可能具有相同的表示形式。 Not guaranteed by the standard though, and there are some exotic systems where this equivalence doesn't hold true. 但是,标准并不能保证这一点,并且有些异类系统并不等效。 So you can cast between void* and a function pointer, but what will happen is undefined behavior. 因此,您可以在void*和函数指针之间进行void* ,但是会发生未定义的行为。 You will be relying on system-specific non-standard extensions. 您将依赖于系统特定的非标准扩展。

Slightly better would be to use a function pointer type such as void (*)(void) as the generic pointer. 更好的方法是使用函数指针类型,例如void (*)(void)作为通用指针。 You can convert to/from different function pointers, what will happen is compiler-specific (implementation-defined behavior). 您可以在不同的函数指针之间进行转换,这将是编译器特定的(实现定义的行为)。 That is, the code will still be non-portable, but at least you don't risk a program crash from invoking undefined behavior. 也就是说,代码仍然是不可移植的,但是至少您不会因调用未定义的行为而使程序崩溃。

It's a matter of operator precedence : The function call operator have higher precedence than the casting operator. 这是运算符优先级的问题 :函数调用运算符的优先级比强制转换运算符的优先级高。

That means your expression (int (*)(int)) functions[0](x) is really equal to (int (*)(int)) (functions[0](x)) . 这意味着您的表达式(int (*)(int)) functions[0](x)实际上等于(int (*)(int)) (functions[0](x))

You need to explicitly add parentheses in the correct places to cast the pointer: ((int (*)(int)) functions[0])(x) . 您需要在正确的位置显式添加括号以强制转换指针: ((int (*)(int)) functions[0])(x)


A much better solution IMO would be to have an array of pointers to functions , so the array elements already is of the correct type: IMO更好的解决方案是拥有一个指向函数的指针数组,因此数组元素已经是正确的类型:

typedef int (*function_ptr)(int);

function_ptr functions[] = { ... };

Then no casting is needed: functions[0](x) . 然后就不需要强制转换: functions[0](x)

Then you also would be safe from the issues mentioned in the answer by Lundin . 这样,您也可以避免Lundin回答中提到的问题。

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

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