为什么myFunction和& myFunction为cimport自定义函数设置了不同的地址?

时间:2015-03-25 17:29:17

标签: c cython

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版本并将其分配给函数指针,如果我用参数调用函数指针,程序将在没有警告的情况下崩溃。

1 个答案:

答案 0 :(得分:2)

如果你看一下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)是,并且有效。