2012-07-06 51 views
8

Tôi đang cố gắng chuyển một số mã Python ctypes từ chương trình dành riêng cho Windows để liên kết với một cổng Linux của thư viện của tôi. Mẫu mã Python ngắn nhất mô tả sự cố của tôi được hiển thị bên dưới. Khi tôi cố gắng thực hiện nó, tôi nhận được một lỗi phân đoạn trong examine_arguments() bằng Python. Tôi đặt một tuyên bố printf trong thư viện của tôi tại cuộc gọi chức năng bị lỗi, nhưng nó không bao giờ được thực hiện, dẫn tôi nghĩ rằng vấn đề là trong mã ctypes.Gỡ lỗi Python ctypes lỗi phân đoạn

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) 

Thư viện của tôi có như sau trong tiêu đề của nó, và một chương trình đơn giản-C làm những gì tôi mô tả ở trên (gọi create_script_environment Tiếp theo set_var) chạy tốt. Nhìn vào thông tin đăng nhập mà thư viện của tôi đang đưa vào bảng điều khiển, sự cố xảy ra khi tôi cố gắng nhập 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); 

Tôi đã thử lùi lại cuộc gọi từ GDB, nhưng tôi không hiểu cách diễn giải kết quả và cũng không thực sự nhiều về việc sử dụng 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() 

Tôi đang thua lỗ về cách tiếp cận vấn đề này. Tôi đã xem xét các chi tiết của các loại cuộc gọi, nhưng tôi không thấy bất cứ điều gì rõ ràng là không chính xác ở đó. Tôi có rơi vào bất kỳ loại tập quán cụ thể nào của nền tảng không?

Chỉnh sửa Có vẻ như đã xảy ra sự cố với kiến ​​trúc 32 bit so với 64 bit trong mô-đun ctypes. Khi tôi kiểm tra điều này một lần nữa với một xây dựng 32-bit của thư viện của tôi và Python 32-bit, nó chạy thành công. Trên 64-bit, nó segfaults tại cùng một vị trí.

+0

tôi sao chép mã này, sắp xếp lại các bit rõ mis-dán, thực hiện một số hiện thực giả của hai chức năng, biên soạn nó cho x86_64, và chạy nó dưới một Python 64 bit 2,7 (Ubuntu Natty, gcc 4.5.2, Python 2.7.1, eglibc 2.13), và mọi thứ hoạt động như mong đợi. Có vẻ như quá sớm để đổ lỗi cho vấn đề trên ctypes ở đây; có lẽ bạn có thể cung cấp một ví dụ phá vỡ hoàn chỉnh hơn? –

+0

Tôi đã dọn sạch ví dụ mã. Có vẻ như segfault có liên quan đến union là một phần của lớp AVS_Value. Khi tôi thay thế nó bằng một cái gì đó như ctypes.c_int hoặc ctypes.c_void_p, chương trình không còn segfaults nữa. Tôi bắt đầu nghĩ rằng vấn đề là với Python được cài đặt trên Ubuntu mặc dù - Tôi đang sử dụng Ubuntu 12.04, GCC 4.6.3, Python 2.7 .. – user1505563

Trả lời

0

Hãy thử sử dụng c_void_p cho đục AVS_ScriptEnvironment*:

avs_create_script_environment.restype = c_void_p 

và:

avs_set_var.argtypes=[c_void_p,ctypes.c_char_p,AVS_Value] 
+0

Đặt rõ ràng kiểu trả về cho c_void_p không giúp ích gì. Tôi không thấy lý do tại sao nó hoặc là, như Python bị treo trước khi vào chức năng tiếp theo, vì vậy không có gì được thực hiện với con trỏ đó. – user1505563