質問

Cでドライバー用のDLLを開発しました。C++でテストプログラムを作成しましたが、DLLは正常に動作します。

今、Pythonを使用してこのDLLを操作したいと思います。ユーザー定義のC構造のほとんどを正常に非表示にしましたが、C構造を使用しなければならない点が1つあります。私はpythonが初めてなので、間違ったことをするかもしれません。

私のアプローチは、Pythonでctypeを使用していくつかの構造を再定義し、変数をDLLに渡すことです。ただし、これらのクラスには、次のような再帰型を含むカスタムリンクリストがあります

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

これは失敗します。これは、EthercatDatagram内ではEthercatDatagramがまだ定義されていないため、パーサーがエラーを返すためです。

DLLが正しく理解できるように、このリンクリストをPythonでどのように表現すればよいですか?

役に立ちましたか?

解決

ほとんど確実にnext_commandをポインターとして宣言する必要があります。それ自体を含む構造を持つことは不可能です(どの言語でも)。

これはあなたが望むものだと思います:

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

他のヒント

その理由

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

機能しないのは、記述子オブジェクトを作成する機械です( next_command 属性にアクセスするためのrel = "nofollow"> PyCStructType_setattro 関数)は、 _fields_への割り当て時にのみ有効になります クラスの属性。 リストに新しいフィールドを追加するだけでは、まったく気付かれません。

この落とし穴を避けるには、 _fields _ 属性の値として常にタプル(リストではなく)を使用します。これにより、属性に新しい値を割り当てて、その場で変更しないでください。

作成後に _fields _ に静的にアクセスする必要があります。

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

EthercatDatagram._fields_.append(("next_command", EthercatDatagram))
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top