C++ 调试Python ctypes分段错误
我正在尝试从Windows特定程序中移植一些PythonC++ 调试Python ctypes分段错误,c++,python,ctypes,C++,Python,Ctypes,我正在尝试从Windows特定程序中移植一些Pythonctypes代码,以链接到我库的Linux端口。下面显示了描述我的问题的最短Python代码示例。当我尝试执行它时,我在Python中的examine_arguments()中收到一个分段错误。在函数调用崩溃时,我在我的库中放置了一个printf语句,但它从未执行过,这让我认为问题出在ctypes代码中 import ctypes avidll = ctypes.CDLL("libavxsynth.so") class AVS_Val
ctypes
代码,以链接到我库的Linux端口。下面显示了描述我的问题的最短Python代码示例。当我尝试执行它时,我在Python中的examine_arguments()
中收到一个分段错误。在函数调用崩溃时,我在我的库中放置了一个printf
语句,但它从未执行过,这让我认为问题出在ctypes代码中
import ctypes
avidll = ctypes.CDLL("libavxsynth.so")
class AVS_Value(ctypes.Structure, object):
def __init__(self, val=None):
self.type=ctypes.c_short(105) # 'i'
self.array_size = 5
self.d.i = 99
class U(ctypes.Union):
_fields_ = [("c", ctypes.c_void_p),
("b", ctypes.c_long),
("i", ctypes.c_int),
("f", ctypes.c_float),
("s", ctypes.c_char_p),
("a", ctypes.POINTER(AVS_Value))]
AVS_Value._fields_ = [("type", ctypes.c_short),
("array_size", ctypes.c_short),
("d", U)]
avs_create_script_environment = avidll.avs_create_script_environment
avs_create_script_environment.restype = ctypes.c_void_p
avs_create_script_environment.argtypes = [ctypes.c_int]
avs_set_var = avidll.avs_set_var
avs_set_var.restype = ctypes.c_int
avs_set_var.argtypes = [ctypes.c_void_p, ctypes.c_char_p, AVS_Value]
env = avs_create_script_environment(2)
val = AVS_Value()
res = avs_set_var(env, b'test', val)
我的库的标题中有以下内容,一个普通C程序执行我上面描述的操作(调用create\u script\u environment
,然后调用set\u var
)运行良好。查看我的库放在控制台上的日志信息,当我尝试输入avs\u set\u var
时会发生崩溃
typedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment;
typedef struct AVS_Value AVS_Value;
struct AVS_Value {
short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong
// for some function e'rror
short array_size;
union {
void * clip; // do not use directly, use avs_take_clip
char boolean;
int integer;
float floating_pt;
const char * string;
const AVS_Value * array;
} d;
};
AVS_ScriptEnvironment * avs_create_script_environment(int version);
int avs_set_var(AVS_ScriptEnvironment *, const char* name, AVS_Value val);
我试图回溯来自GDB的调用,但我不知道如何解释结果,也不知道如何使用GDB
#0 0x00007ffff61d6490 in examine_argument () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#1 0x00007ffff61d65ba in ffi_prep_cif_machdep () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#2 0x00007ffff61d3447 in ffi_prep_cif () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#3 0x00007ffff61c7275 in _ctypes_callproc () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#4 0x00007ffff61c7aa2 in PyCFuncPtr_call.2798 () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#5 0x00000000004c7c76 in PyObject_Call ()
#6 0x000000000042aa4a in PyEval_EvalFrameEx ()
#7 0x00000000004317f2 in PyEval_EvalCodeEx ()
#8 0x000000000054b171 in PyRun_FileExFlags ()
#9 0x000000000054b7d8 in PyRun_SimpleFileExFlags ()
#10 0x000000000054c5d6 in Py_Main ()
#11 0x00007ffff68e576d in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#12 0x000000000041b931 in _start ()
我不知道如何处理这个问题。我已经查看了呼叫类型的详细信息,但是我没有看到任何明显不正确的地方。我是否有任何特定于平台的类型用法
编辑ctypes模块中的32位与64位体系结构似乎存在问题。当我用我的库的32位构建和32位Python再次测试它时,它成功地运行了。在64位上,它会在同一位置隔离故障。对于不透明的
AVS\u脚本环境*
尝试使用c\u void\u p
:
avs_create_script_environment.restype = c_void_p
以及:
显式地将返回类型设置为c_void_p没有帮助。我也不明白为什么会这样,因为Python在进入下一个函数之前崩溃了,所以没有对指针做任何处理。这会对64位代码产生影响,因为指针会被截断为
c_int
(32位)。我复制了这段代码,重新排列了明显错误粘贴的位,对这两个函数进行了一些虚拟实现,为x86_64编译,并在64位Python 2.7(UbuntuNatty、GCC4.5.2、Python 2.7.1、eglibc 2.13)下运行,一切正常。把问题归咎于ctypes似乎为时过早;也许你可以提供一个更完整的示例?我整理了代码示例。似乎SEGFULT与作为AVS_值类一部分的union有关。当我用ctypes.c_int或ctypes.c_void_p之类的东西替换它时,程序就不会再出现故障。我开始认为问题出在Ubuntu上安装的Python上——我使用的是Ubuntu 12.04、GCC 4.6.3、Python 2.7..您的boolean
变量是typechar
,但在Python中,您已经声明b
为c_long
。但是,代码看起来是正确的,实际上是正常的,还有我的虚拟实现,所以问题可能出在C代码中。
avs_set_var.argtypes=[c_void_p,ctypes.c_char_p,AVS_Value]