2009-08-04 53 views
8

Tôi đã phát triển một DLL cho một trình điều khiển trong C. Tôi đã viết một chương trình thử nghiệm trong C++ và DLL hoạt động tốt.python ctype cấu trúc đệ quy

Bây giờ tôi muốn can thiệp với DLL này bằng cách sử dụng Python. Tôi đã ẩn thành công hầu hết các cấu trúc C do người dùng định nghĩa nhưng có một điểm mà tôi phải sử dụng các cấu trúc C. Tôi khá mới để python vì vậy tôi có thể nhận được những điều sai trái.

Cách tiếp cận của tôi là xác định lại một vài cấu trúc trong python bằng cách sử dụng ctype sau đó chuyển biến cho DLL của tôi. Tuy nhiên, trong những lớp tôi có một danh sách tùy chỉnh liên kết, trong đó có các loại đệ quy như sau

class EthercatDatagram(Structure): 
    _fields_ = [("header", EthercatDatagramHeader), 
       ("packet_data_length", c_int), 
       ("packet_data", c_char_p), 
       ("work_count", c_ushort), 
       ("next_command", EthercatDatagram)] 

này thất bại, vì EthercatDatagram bên trong, EthercatDatagram chưa được xác định để phân tích cú pháp trả về một lỗi.

Tôi nên trình bày danh sách được liên kết này bằng python để DLL của tôi hiểu chính xác như thế nào?

Trả lời

15

Bạn gần như chắc chắn muốn khai báo next_command làm con trỏ. Có một cấu trúc chứa chính nó là không thể (trong bất kỳ ngôn ngữ nào).

Tôi nghĩ rằng đây là những gì bạn muốn:

class EthercatDatagram(Structure): 
    pass 
EthercatDatagram._fields_ = [ 
    ("header", EthercatDatagramHeader), 
    ("packet_data_length", c_int), 
    ("packet_data", c_char_p), 
    ("work_count", c_ushort), 
    ("next_command", POINTER(EthercatDatagram))] 
+1

"là không thể (bằng bất kỳ ngôn ngữ nào)" - đó là đúng về c/C++/java-phong cách structs hoặc các lớp học, nhưng trong ngôn ngữ với các loại dữ liệu đại số nó không chỉ có thể nhưng cũng rất phổ biến. ví dụ. 'data List a = Nhược điểm a (Danh sách a) | Nil' trong ngôn ngữ ML-gia đình (ocaml/haskell/SML/etc). – sinelaw

-1

Bạn sẽ phải truy cập _fields_ tĩnh sau khi đã tạo.

class EthercatDatagram(Structure) 
    _fields_ = [...] 

EthercatDatagram._fields_.append(("next_command", EthercatDatagram)) 
+1

Điều này không hiệu quả. Nó biên dịch và chạy, nhưng cố gắng thực sự sử dụng một thể hiện của lớp cho một lỗi: AttributeError: 'EthercatDatagram' đối tượng không có thuộc tính 'next_command' – user9876

+0

Câu trả lời đúng là dưới đây, như được đăng bởi user9876 Trước tiên bạn phải khai báo lớp với 'pass', sau đó khai báo các trường trong cuộc gọi thứ hai. Hãy suy nghĩ về nó như là tuyên bố về phía trước. – bpescatore

0

Lý do tại sao

EthercatDatagram._fields_.append(("next_command", EthercatDatagram)) 

không hoạt động là các máy móc thiết bị tạo ra các đối tượng mô tả (xem nguồn gốc của PyCStructType_setattro chức năng) để truy cập thuộc tính next_command được kích hoạt chỉ khi gán thành thuộc tính _fields_ của lớp. Chỉ cần thêm trường mới vào danh sách hoàn toàn không được chú ý.

Để tránh sự cố này, hãy luôn sử dụng một bộ (và không phải danh sách) làm giá trị thuộc tính _fields_: điều đó sẽ làm rõ rằng bạn phải gán giá trị mới cho thuộc tính và không sửa đổi nó tại chỗ.

Các vấn đề liên quan