11

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

ここで、Pythonを使用してこのDLLと対話したいと思います。ユーザー定義のC構造体のほとんどを正常に非表示にしましたが、C構造体を使用する必要があるポイントが1つあります。私はPythonにかなり慣れていないので、物事を間違える可能性があります。

私のアプローチは、ctypeを使用してPythonでいくつかの構造を再定義してから、変数を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でどのように表現する必要がありますか?

4

3 に答える 3

16

ほぼ確実に、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))]
于 2009-08-04T16:12:55.377 に答える
1

理由

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

機能しないのは、属性PyCStructType_setattroにアクセスするための記述子オブジェクト(関数のソースを参照)を作成する機構が、クラスの属性への割り当て時にのみnext_commandアクティブ化されることです。新しいフィールドをリストに追加するだけでは、まったく気付かれません。_fields_

この落とし穴を回避するには、属性の値として常にタプル(リストではなく)を使用します。これにより、_fields_属性に新しい値を割り当て、その場で変更しない必要があることが明確になります。

于 2013-07-24T12:11:36.527 に答える
-2

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

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

EthercatDatagram._fields_.append(("next_command", EthercatDatagram))
于 2009-08-04T15:33:59.910 に答える