Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ctypes cdecl在调用返回结构的gcc编译dll时提供4个字节_Python_Windows_Gcc_Ctypes - Fatal编程技术网

Python ctypes cdecl在调用返回结构的gcc编译dll时提供4个字节

Python ctypes cdecl在调用返回结构的gcc编译dll时提供4个字节,python,windows,gcc,ctypes,Python,Windows,Gcc,Ctypes,我有一个c库(花栗鼠),我想用ctypes调用它。但是,它在返回结构的函数上失败 我得到的错误是 File "qw.py", line 19, in <module> b = cpBBNew3(1,2,3,4) ValueError: Procedure called with not enough arguments (4 bytes missing) or wrong calling convention 在cpBB.c中 cpBB cpBBNew3(cpF

我有一个c库(花栗鼠),我想用ctypes调用它。但是,它在返回结构的函数上失败

我得到的错误是

File "qw.py", line 19, in <module>
b = cpBBNew3(1,2,3,4)
ValueError: Procedure called with not enough arguments (4 bytes missing) or wrong calling convention
在cpBB.c中

cpBB cpBBNew3(cpFloat l、cpFloat b、cpFloat r、cpFloat t){
cpBB-bb={l,b,r,t};
返回bb;
}
编撰

gcc-O3-std=gnu99-共享-c

gcc-O3-std=gnu99-shared-s

然后python看起来像

从ctypes导入*
chipmunk_lib=cdll.LoadLibrary(“”“C:/code/pymunk/trunk/pymunk/chipmunk.dll“”)
cpBB类(结构):
通过
cpBB.\u包装=4
cpBB.\u字段=[
('l',c_double),
('b',c_-double),
('r',c_-double),
('t',c_double),
]
cpBBNew3=花栗鼠_lib.cpBBNew3
cpBBNew3.restype=cpBB
cpBBNew3.argtypes=[c_-double,c_-double,c_-double,c_-double]
b=cpBBNew3(1,2,3,4)

如果我使用-mrtd编译并使用windl(使用stdcall),这个特定的示例就可以工作。但是,在整个库中使用stdcall在使用优化和新版本的GCC编译时会在库的其他部分产生分段错误,这就是为什么让cdecl正常工作的原因。

取决于结构和编译器/平台的大小,cdecl可以通过在正常参数之前将隐藏指针传递给调用方分配的结构来返回结构。请尝试以下操作:

b = cpBB()
cpBBNew3(byref(b),1,2,3,4)

请注意,如果使用stdcall和优化会导致分段错误,您的代码中可能存在使用cdecl进行掩蔽的错误。@HarryJohnston我在这里询问了这个错误:从Dashwuff的回答来看,似乎我不应该使用stdcall,这意味着cdecl必须是解决方法?您必须使用该函数所期望的调用约定调用外部函数,因此,如果您需要相同的函数指针能够指向外部(C库)函数或内部(您的代码)函数,那么,是的,您必须坚持使用cdecl。(如果您找不到更好的解决方案,一个解决方法是更改cpBBNew3,使其将指向结构的指针作为参数之一并返回void。)