[英]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
. 我注意到你声明AAA
和BBB
是PChar
类型。 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.