LINUX.ORG.RU

Как реализовать односвязный Си список в python через ctypes?

 , ,


0

1

Целый день мучаюсь и не получается реализовать сишный список:


typedef struct List List;

typedef struct List
{
    unsigned char message;
    void* data;
    List* next;
};

Как все это сделать на питоне через ctypes?
Вот как я пробовал:

# Объявляем нашу структуру таким образом, чтоб можно было ссылаться на саму себя
class MessageStruct(ctypes.Structure):
    pass

MessageStruct._fields_ = [('message', ctypes.c_ubyte),
                          ('data', ctypes.c_void_p),
                          ('next', ctypes.POINTER(MessageStruct))]
После созданию голову списка вот так:
struct = MessageStruct()
struct.message = ctypes.c_ubyte(0)
struct.data = ctypes.c_void_p(0)
struct.next = None

# Буду работать только с указателем на голову
struct_p = ctypes.pointer(struct)

Дальше я объявил 2 функции: добавления нового элемента и вывод списка:

def add_message(message_struct, message, data):
    current_struct = message_struct
    while current_struct.contents.next:
        current_struct.contents = current_struct.contents.next

    new_struct = MessageStruct()
    new_struct.message = message
    new_struct.data = data
    new_struct.next = None
    current_struct.contents.next = ctypes.pointer(new_struct)

def print_messages(message_struct):
    current_struct = message_struct
    while current_struct.contents:
        print('message:', current_struct.contents.message,
              'data:', current_struct.contents.data)
        current_struct.contents = current_struct.contents.next
B вызываю их вот так:
add_message(struct_p, 5, 0)
add_message(struct_p, 7, 0)
add_message(struct_p, 3, 0)

print_messages(struct_p)
Но вывод идет в бесконечном цикле:
message: 0 data: None
message: 0 data: None
message: 0 data: None
message: 0 data: None
message: 0 data: None
.....

Что я делаю не так?
Заранее спасибо!

Ответ на: комментарий от Glaciuse

вроде логика правильная. А сам питон я плохо знаю.

PS: я и не знал, что питон ТАК может…

emulek
()
#!/usr/bin/python3

import ctypes

# Объявляем нашу структуру таким образом, чтоб можно было ссылаться на саму себя
class MessageStruct(ctypes.Structure):
    pass

MessageStruct._fields_ = [('message', ctypes.c_ubyte),
                          ('data', ctypes.c_void_p),
                          ('next', ctypes.POINTER(MessageStruct))]

null_ptr = ctypes.POINTER(MessageStruct)()

struct = MessageStruct()
struct.message = ctypes.c_ubyte(0)
struct.data = ctypes.c_void_p(0)
struct.next = ctypes.POINTER(MessageStruct)()

struct_p = ctypes.pointer(struct)

def add_message(message_struct, message, data):
    i = message_struct.contents
    while i.next:
        i = i.next.contents

    new_struct = MessageStruct()
    new_struct.message = message
    new_struct.data = data
    new_struct.next = None
    i.next = ctypes.pointer(new_struct)

def print_messages(message_struct):
    i = message_struct
    while bool(i):
        i = i.contents
        print('message:', i.message,
              'data:', i.data)
        i = i.next
    print()

def p(a):
    print("msg:",  a.message)
    print("data:", a.data)
    print("next:", a.next)
    print()

add_message(struct_p, 5, 0)
add_message(struct_p, 7, 0)
add_message(struct_p, 3, 0)

p(struct)
p(struct_p.contents)
print_messages(struct_p)
p(struct_p.contents)
anonymous
()
Ответ на: комментарий от Gvidon

Я думаю, что автор делает это в качестве тренировочного задания, а не для практических нужд, так что хлеб и троллейбус тут не уместны.

Aswed ★★★★★
()

напиши модуль обращающий питоновые списки в твои сишные

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.