为什么 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)
是,并且有效。
在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)
是,并且有效。