11

ctypesWindows 固有のプログラムから一部の Python コードを移植して、ライブラリの Linux ポートにリンクしようとしています。私の問題を説明する最短の Python コード サンプルを以下に示します。実行しようとすると、examine_arguments()Python でセグメンテーション違反が発生します。クラッシュした関数呼び出しでライブラリにステートメントを配置し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_script_environment後に が続くset_var) は正常に動作します。私のライブラリがコンソールに出力しているログ情報を見ると、入力しようとするとクラッシュが発生しますavs_set_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 ビットでは、同じ場所でセグメンテーション違反が発生します。

4

1 に答える 1

0

c_void_popaque に使用してみてくださいAVS_ScriptEnvironment*:

avs_create_script_environment.restype = c_void_p

と:

avs_set_var.argtypes=[c_void_p,ctypes.c_char_p,AVS_Value]
于 2012-07-07T08:05:33.003 に答える