3

現在、 python4delphiを使用して Python モジュールを作成しています。標準の C API 関数PyArg_ParseTupleAndKeywordsを使用したいと思います。

ドキュメントからわかるように、署名は次のとおりです。

int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format,
    char *keywords[], ...)

現在、この関数は python4delphi にラップされていないため、自分で追加しました。

PyArg_ParseTupleAndKeywords: function (args, kw: PPyObject; format: PAnsiChar; 
    keywords: array of PAnsiChar {;...}): Integer; cdecl varargs;
....
PyArg_ParseTupleAndKeywords := Import('PyArg_ParseTupleAndKeywords');

私が抱えている問題は、このスニペットのような方法で使用しようとすると、アクセス違反エラーが発生することです。

function PyScript_MyFunction(pself, args, keywds : PPyObject) : PPyObject; cdecl;
var
  AAA, BBB : PChar;
  kwlist : array[0..2] of PAnsiChar;
begin
  kwlist[0] := 'AAA';
  kwlist[1] := 'BBB';
  kwlist[2] := nil;

  BBB := 'BBB';
  with GetPythonEngine do
  begin
    if (PyErr_Occurred() = nil) and (PyArg_ParseTupleAndKeywords(args, keywds,
        's|s:Script_MyFunction', kwlist, @AAA, @BBB) <> 0) then
    begin
      Result := VariantAsPyObject(MyFunction(AAA, BBB));
    end
    else
      Result := nil;
  end;
end;

//Module is my Python module I am working with

Module.AddMethodWithKeywords('Wrapped', @PyScript_MyFunction, 'no doc');

どうすればこれを修正できますか? このようなエラーをデバッグする方法はありますか?

4

1 に答える 1

4

keywordsパラメータの翻訳が正しくありません。Delphi オープン配列を使用しました。Delphi オープン配列では、配列内の最後の項目のインデックスと、配列の最初の要素へのポインタという 2 つのものが渡されます。Delphi オープン アレイは、相互運用に使用されることはありません。

そのパラメータを次のように宣言する必要があります。

keywords: PPAnsiChar

へのポインタPAnsiCharです。

次のように関数を呼び出します。

PyArg_ParseTupleAndKeywords(..., @kwlist[0], ...) 

個人的には、動的配列を使用してパラメーターを準備します。

var
  kwlist: TArray<PAnsiChar>;

次のように初期化します。

kwlist := TArray<PAnsiChar>.Create('AAA', 'BBB', nil);

そして、次のように渡します。

PPAnsiChar(kwlist)

または、必要に応じて次のようにします。

@kwlist[0]

後者は少なくともタイプセーフです。


あなたが と型であると宣言AAAしたことに注意してください。きっとそうなるはずです。BBBPCharPAnsiChar


他のすべてのパラメーターが正しく準備されているかどうかはわかりません。私はこの特定の API 呼び出しに慣れていません。確かに、上で説明したことは、最初に取り組むべき最も重要な問題です。

呼び出し元は、返された文字列の割り当てをどのように解除する必要があるのだろうか? あなたはそうすることが期待されていると思います。

于 2014-04-19T14:12:06.333 に答える