3

次のシグネチャを持つ関数を公開しているデリー DLL があります。

Function MyFunc(ObjID : Cardinal) : TMyRec; stdcall;

レコードは次のように定義されています。

type TMyRec = record
  Count : Cardinal;
  Items : array of TMyItemRec;
end;

type TMyItemRec = record
  ID : Cardinal;
  Params : array of String;
end;

私の質問は、Python ctypes で dll を呼び出す MyFunc の結果にアクセスするにはどうすればよいですか? 型を模倣する 2 つのクラスをコーディングしました

from ctypes import *
class TMyItemRec(Structure):
    _fields_ = [("ID", c_int), ("Params", POINTER(c_wchar_p))]

class TMyRec(Structure):
    _fields_ = [("Count", c_int), ("Params", POINTER(TMyItemRec))]

しかし、次のようなデータを読み取ろうとすると:

my_dll = windll.Script

def GetMyRec(ID):
    my_dll.MyFunc.argtypes = [c_uint]
    my_dll.MyFunc.restype = TClilocRec

    return my_dll.Script_GetClilocRec(ID)

アクセス違反のエラーが発生します。

4

1 に答える 1

5

動的配列などの Delphi マネージド型を Delphi 以外のコードに渡すことはできません。これらのデータ型で関数を呼び出すことは期待できません。

インターフェイスを再設計する必要があります。単純型と単純型を含むレコードを使用する必要があります。配列が必要な場合は、Delphi 固有のマネージド型を使用するのではなく、最初の要素へのポインタと長さを渡す必要があります。相互運用インターフェイスを設計する方法のテンプレートとして Windows API を使用します。

もう 1 つ対処する必要があるのは、Delphi では関数の戻り値の処理が他のほとんどの Windows コンパイラとは異なるということです。したがって、レジスタに収まらないレコードは、関数の戻り値としてではなく、var パラメータとして渡す必要があります。

于 2013-06-24T22:15:50.457 に答える