我在 C++ 程序中有一个奇怪的 typedef 语句,由 Py++ 生成。
double radius(int); // function to be wrapped
typedef double (*radius_function_type)(int);
// bp::def is a function for wrapping
bp::def("radius", radius_function_type(&radius));
我发现上面的
typedef
语句不是我们熟悉的形式:
typedef complex_type simple_alias;
相反,它是一种声明指向函数的指针的方法,该函数以
int
作为参数并返回 double
(与原型相同)。
那么如何用函数的地址作为参数来调用函数的指针(无需解引用)呢?这也与原型不相符。谁来解释一下吧!
它没有声明函数指针变量,而是声明一个名为
radius_function_type
的函数指针 typedef。 radius_function_type(&radius)
只是函数指针本身的(冗余)转换。 (一元 &
地址运算符也是多余的;对于函数来说,radius
和 &radius
是同一件事。)
从底层来看,调用函数只是根据底层调用约定将参数放置在某个位置(通常在堆栈上),然后跳转到内存地址。因此,如果编译器知道函数指针类型(函数签名)和指针值本身,则它可以仅使用指针调用函数。
你的问题令人困惑。你问这是做什么的吗:
radius_function_type(&radius)"
这只是一个 C++ 类型转换,有点像:
radius (int (42));
但是由于 radius 已经是 radius_function_type 类型,那么你可以轻松地做到:
bp::def("radius", radius);
但由于这是由 Py++ 生成的代码,因此它可能对输出格外小心。
嗯...这有点类似于 C 和 C++ 中数组与指针的关系。函数的名称基本上也是一个指针。从这个角度来看,给出一个定义也就不足为奇了:
int foo(int a, int b)
{
return a + b;
}
您可以通过函数名称的指针直接进行调用:
foo(1, 2);
或者将该值存储在一个单独的变量中,该变量必须声明为指针:
int (*pointer)(int, int) = foo;
pointer(1, 2);
在这种情况下,我们可以直接通过指针变量来调用,也不需要通过写
&foo
来显式“获取”函数的地址。
取消引用(以您认为的方式)函数指针意味着:访问代码内存,就像访问数据内存一样。
函数指针不应该以这种方式取消引用。相反,它被称为。
我会使用名称“取消引用”与“调用”并排。没关系。
无论如何:C 的设计方式是函数名标识符和保存函数指针的变量都具有相同的含义:代码内存的地址。它允许通过在标识符或变量上使用 call () 语法来跳转到该内存。
函数指针基本上就是需要调用的函数的地址。要调用函数指针指向的函数,您可以将函数指针视为您要调用的函数的名称。调用它本身的行为执行取消引用;不需要显式取消引用。
函数指针语法可以看起来像指针(带有 & 和 *),也可以省略。 正如 @unwind 已经指出的那样,它与处理数组的方式类似,其中裸数组与指针类似,并且您可以选择在数组前面加上 & 来获取地址。