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を使用)に機能します。ただし、ライブラリ全体でstdcallを使用すると、最適化と新しいバージョンのGCCを使用してコンパイルすると、ライブラリの他の部分でセグメンテーション違反が発生します。そのため、cdeclを機能させると便利です。

4

1 に答える 1

0

構造体とコンパイラ/プラットフォームのサイズに応じて、cdecl は、通常のパラメーターの前に、呼び出し元が割り当てた構造体への隠しポインターを渡すことによって、構造体を返す場合があります。次のことを試してください。

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