python函数指针 python ctypes 指针

用C++/Qt 写Python调试器遇到的问题在C++中,“类函数指针”和传统的“函数指针”,是两个完全不同的东西 。
你取一个类的成员函数的地址,得到的是一个类函数指针,也叫成员函数指针 。即使你的成员函数定义看起来和普通函数原型完全一样,它也和这个原型的普通函数指针完全不同 , 彼此之间不能转换 。
PyEval_SetTrace要求传入的是一个传统的函数指针,你传入一个类函数指针,当然是不行的 。编译器报错是说无法将一个类函数指针转换为函数指针 。
C++的类函数指针 , 是一个非常难用的东西 , 有非常多奇怪的特性,而且不同编译器对它的支持大不相同,是C++著名的复杂性来源之一,建议不要使用 。
你想要的东西 , 实际上是一个“委托”的概念,不过可惜的是C++并不支持委托 。使用boost::function可以实现类似功能,但python的C API接口却不支持boost::function,所以也不行 。
你这种情况,最简单的方法还是用传统的函数指针 , 使用普通函数包装下类的成员函数,然后把普通函数的指针传给python 。
python中,能对函数传递文件指针类型的参数吗如果你用C给Matlab写过MEX程序,那么这个问题是很容易理解的(好像每次讨论Python问题时python函数指针我总是把Matlab搬了出来…… 《在Matlab中把struct当成Python中的Dictionary使用》《Matlab和Python的几种数据类型的比较》) 。
既然提到了MEX,就简单说一下:
一个Matlab可能形如
function ret=add3(a,b,c)
如果在C的层面实现这个函数,就会看到另一种景象:
void mexFunction(int nlhs,mxArray * plhs[],int nrhs,const mxArray * prhs[])
a,b,c三个参数的地址放在一个指针数组里,然后把这个指针数组的首地址作为参数prhs传递给函数,这说明Matlab函数的参数是传递指针的,而不是值传递 。
纵然是传递的指针,但是却不能在函数里改变实参的值,因为标记为“const”了 。
Python是开放源码的,我没有看 。所以下面很多东西是猜的 。
Python在函数的参数传递时用的什么手法?实验一下(使用ActivePython2.5):
首先介绍一个重要的函数:
help(id)
Help on built-in function id in module __builtin__:
id(...)
id(object) - integer
Return the identity of an object.This is guaranteed to be unique among
simultaneously existing objects.(Hint: it's the object's memory address.)
看最后括号里那句:Hint:it's the object's address.(它是对象的地址)
有了这个函数,下面的事情就方便多了 。
a=0
id(a)
3630228
a=1
id(a)
3630216
可以看出,给a赋一次值,a的address就改变了 。在C的层面看 , (也许真实情况不是下面的样子,但作为一个类比应该还是可以的):
void * pa;
pa=malloc(sizeof(int));
*(int *)pa=0;
free(pa);
pa=malloc(sizeof(int));
*(int *)pa=1;
Python中每次赋值会改变变量的address,分配新的内存空间,所以Python中对于类型不像C那样严格要求 。
下面看看Python函数参数传递时到底传的什么:
有一个函数:
def changeA(a):
...print id(a)
...a=100
...print id(a)
设定一个变量var1:
var1=10
id(var1)
3630108
changeA(var1)
3630108
3631012
var1
10
调用函数后 , 从两次print的结果可以看出,传递确实是地址 。但是即便如此,在函数内对形参的修改不会对实参造成任何实质的影响,因为对形参的重新赋值,只是改变了形参所指向的内存单元(changeA里两次调用print id(a)得到不同的结果),却没有改变实参的指向 。在C的层面看也许类似下面的情节:

推荐阅读