在64位下,把一些库封装成C函数,然后编译成so文件供python调用,结果发生了崩溃。
今天试验后发现:如果C函数返回void*等类型,把返回值赋值到python变量后被截断,只剩下低32位的值。
因此,如果C函数中的指针在0xffffffff以上的地址的时候,返回到python中就会被截断。如果再继续使用这个被截断后的地址值,就会发生崩溃。
下面是模拟崩溃的代码:
//C
void* create_object()
{
return new int(0);
}
void free_object(void* obj)
{
delete (int*)obj;
}
#python中这样调用
so = cdll.LoadLibrary('xxxx.so')
obj = so.create_object() #这里被截断
so.free_object(obj) #这里发生崩溃
=====================================================
解决办法也比较简单,不要通过返回值传递指针,而通过指针参数返回:
void create_object(uint64_t* out)
{
*out = (uint64_t)new int(0);
}
void free_object(void* obj)
{
delete (int*)obj;
}
#python中这样调用
so = cdll.LoadLibrary('xxxx.so')
obj = ctypes.c_ulonglong(0)
so.create_object(ctypes.byref(obj))
obj = ctypes.c_void_p(obj.value)
so.free_object(obj)
这里要注意:发现python中的对象的地址都在0xffffffff之内,所以使用byref没发现问题。
byref是否会截断指针,这个还没试验出来。
没有评论:
发表评论