为什么 myFunction 和 myFunction 导入自定义函数的地址不同?

Why myFunction and &myFunction have different addresses for cimport customized functions?

another.pyx,我有

cdef double myadd(double a, double b):
    cdef double c = a + b
    return c

another.pxd,我有

cdef double myadd(double a, double b)

如果我运行这个:

from another cimport myadd
from libc.math cimport exp
from libc.stdio cimport sprintf
def test():
    cdef char s[80]
    sprintf(s, "%p", <void *> myadd)
    print s
    sprintf(s, "%p", <void *> &myadd)
    print s
    sprintf(s, "%p", <void *> exp)
    print s
    sprintf(s, "%p", <void *> &exp)
    print s


0x7f5ccc638130
0x7f5ccc62d5e0
0x32b9622f90
0x32b9622f90

为什么 myadd&myadd 不同?事实证明,如果我使用 &myadd 版本并将其分配给函数指针,如果我使用参数调用函数指针,程序将在没有警告的情况下崩溃。

如果您查看 Cython 创建的 .c,您会看到它声明的内容是:

/* Module declarations from 'another' */
static double (*__pyx_f_7another_myadd)(double, double); /*proto*/

然后打印(中间省略了很多):

  sprintf(__pyx_v_s, __pyx_k_p, ((void *)__pyx_f_7another_myadd));
  sprintf(__pyx_v_s, __pyx_k_p, ((void *)(&__pyx_f_7another_myadd)));

__pyx_f_7another_myadd 是指向函数的指针。如果你让它指向某个特定的函数,它将包含它在 __pyx_f_7another_myadd 中的地址,但 __pyx_f_7another_myadd 本身的地址(即 &__pyx_f_7another_myadd 保持不变)。由于函数声明本身确实是指向函数的指针,也许是一个普通的 C++ 示例,它可以看出发生了什么:

#include <iostream>

int funcion(int a, int b)
{

  std::cout << a+b << std::endl;
}

int (*func) (int,int);

int main()
{
  std::cout << (void*) funcion << std::endl;
  std::cout << (void*) &funcion << std::endl;

  func = funcion;

  std::cout << (void*) func << std::endl;
  std::cout << (void*) &func << std::endl;
}

0x400886
0x400886
0x400886
0x601198

这里 funcion 被声明为一个函数本身,所以它是它自己的指针(因此两个相等的初始地址)。另一方面,func 是一个函数指针:它存储 funcion 地址(第三行),但它有自己的地址(因此第四行不同)。

(&func) (1,2) 这样的东西不会编译,因为这个表达式不是函数调用,但 (func) (1,2) 是,并且有效。