简体   繁体   English

如何在Delphi中使用C API函数PyArg_ParseTupleAndKeywords?

[英]How do I use C API function PyArg_ParseTupleAndKeywords in Delphi?

I am currently writing a Python module using python4delphi . 我目前正在使用python4delphi编写Python模块。 I would like to use the standard C API Function PyArg_ParseTupleAndKeywords . 我想使用标准的C API函数PyArg_ParseTupleAndKeywords

As you can see from the documentation the signature is so: 从文档中可以看出签名是这样的:

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

Now this function is not wrapped in python4delphi so I've added it by myself: 现在这个函数没有包含在python4delphi中,所以我自己添加了它:

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

The problem I have is that I am getting an access violation error when I try to use it in way similar to this snippet: 我遇到的问题是,当我尝试以类似于此代码段的方式使用它时,我收到了访问冲突错误:

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');

How can I fix this? 我怎样才能解决这个问题? Is there a way to debug such kind of errors? 有没有办法调试这种错误?

Your translation of the keywords parameter is incorrect. 您对keywords参数的翻译不正确。 You've used a Delphi open array. 你使用过Delphi开放式数组。 A Delphi open array results in two things being passed, the index of the final item in the array, and the pointer to the first element of the array. Delphi open数组导致传递两件事,数组中最后一项的索引,以及指向数组第一个元素的指针。 Delphi open arrays are simply never to be used for interop. Delphi开放式数组绝不会用于互操作。

You need to declare that parameter like so: 您需要声明该参数,如下所示:

keywords: PPAnsiChar

That is a pointer to PAnsiChar . 这是指向PAnsiChar的指针。

Call the function like this: 像这样调用函数:

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

Personally I would use a dynamic array to prepare your parameter: 我个人会使用动态数组来准备你的参数:

var
  kwlist: TArray<PAnsiChar>;

Initialise it like this: 像这样初始化它:

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

And pass it like this: 并传递它:

PPAnsiChar(kwlist)

or like this if you prefer: 或者喜欢这个,如果您愿意:

@kwlist[0]

The latter is typesafe at least. 后者至少是类型安全的。


I note that you declared AAA and BBB to be of type PChar . 我注意到你声明AAABBBPChar类型。 Surely that should be PAnsiChar . 当然应该是PAnsiChar


I'm far from sure that you've prepared all the other parameters correctly. 我很不确定你是否正确准备了所有其他参数。 I'm not familiar with this particular API call. 我不熟悉这个特殊的API调用。 For sure though, what I describe above is the first and most important problem to tackle. 可以肯定的是,我上面描述的是第一个也是最重要的问题。

I do wonder how you the caller are expected to deallocate the strings that are returned to you? 我想知道调用者如何释放返回给你的字符串? I presume that you are expected to do that. 我认为你应该这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM