Pergunta

Eu já desenvolveu um DLL para um motorista em C. Eu escrevi um programa de teste em C ++ eo DLL funciona bem.

Agora, eu gostaria de interract com este DLL usando Python. Eu tenho escondido com sucesso a maioria das estruturas C definidas pelo usuário, mas há um ponto em que eu tenho que usar estruturas C. Eu sou um pouco novo para python para que eu possa fazer as coisas erradas.

A minha abordagem é redefinir algumas estruturas em python usando ctype em seguida, passar a variável para a minha DLL. No entanto nestes classe Eu tenho uma lista ligada personalizado que contém tipos recursiva como segue

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

Esta falha, porque EthercatDatagram dentro, EthercatDatagram ainda não estiver definido de modo que o analisador retorna um erro.

Como devo representar esta lista ligada em python para que a minha DLL entende-lo corretamente?

Foi útil?

Solução

Você certamente quer declarar NEXT_COMMAND como um ponteiro. Ter uma estrutura que contém em si não é possível (em qualquer idioma).

Eu acho que isso é o que você quer:

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))]

Outras dicas

A razão pela qual

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

não funciona é que a máquina que cria os objetos descritor (ver a fonte do PyCStructType_setattro função) para acessar o atributo next_command é ativado apenas mediante atribuição para o atributo _fields_ da classe. Apenas acrescentando o novo campo para a lista continua completamente despercebido.

Para evitar essa armadilha, use sempre um tuple (e não uma lista) como o valor do atributo _fields_: que vai deixar claro que você tem que atribuir um novo valor para o atributo e não modificá-lo no lugar <. / p>

Você terá acesso _fields_ estaticamente depois de ter criado-lo.

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

EthercatDatagram._fields_.append(("next_command", EthercatDatagram))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top