3

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

我得到的错误是

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

这是(相关的)c 代码:在 cpBB.h

typedef struct cpBB {
    cpFloat l, b, r ,t;
} cpBB;
cpBB cpBBNew3(cpFloat l, cpFloat b, cpFloat r, cpFloat t);

在 cpBB.c

cpBB cpBBNew3(cpFloat l, cpFloat b, cpFloat r, cpFloat t) {
    cpBB bb = {l, b, r, t};
    return bb;
}

编译

gcc -O3 -std=gnu99 -shared -c

gcc -O3 -std=gnu99 -shared -s

然后python看起来像

from ctypes import *

chipmunk_lib = cdll.LoadLibrary('''C:/code/pymunk/trunk/pymunk/chipmunk.dll''')

class cpBB(Structure):
    pass
cpBB._pack_ = 4
cpBB._fields_ = [
    ('l', c_double),
    ('b', c_double),
    ('r', c_double),
    ('t', c_double),
]

cpBBNew3 = chipmunk_lib.cpBBNew3
cpBBNew3.restype = cpBB
cpBBNew3.argtypes = [c_double, c_double, c_double, c_double]

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

如果我使用 -mrtd 编译并使用 windll(使用 stdcall),则此特定示例有效。然而,当使用优化和新版本的 GCC 编译时,在整个库上使用 stdcall 会在库的其他部分产生分段错误,这就是为什么让 cdecl 工作会很好的原因。

4

1 回答 1

0

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

b = cpBB()
cpBBNew3(byref(b),1,2,3,4)
于 2013-02-07T17:27:49.073 回答