我目前正在使用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');
我该如何解决这个问题?有没有办法调试这种错误?
答案 0 :(得分:4)
keywords
参数的翻译不正确。您使用过Delphi开放式阵列。 Delphi open数组导致传递两件事,数组中最后一项的索引,以及指向数组第一个元素的指针。 Delphi开放数组绝不会用于互操作。
您需要声明该参数:
keywords: PPAnsiChar
这是指向PAnsiChar
的指针。
像这样调用函数:
PyArg_ParseTupleAndKeywords(..., @kwlist[0], ...)
就个人而言,我会使用动态数组来准备你的参数:
var
kwlist: TArray<PAnsiChar>;
初始化如下:
kwlist := TArray<PAnsiChar>.Create('AAA', 'BBB', nil);
并按照这样传递:
PPAnsiChar(kwlist)
或者喜欢这个,如果您愿意:
@kwlist[0]
后者至少是类型安全的。
我注意到您声明AAA
和BBB
属于PChar
类型。当然应该是PAnsiChar
。
我很不确定您是否已正确准备好所有其他参数。我不熟悉这个特定的API调用。可以肯定的是,我上面描述的是第一个也是最重要的问题。
我想知道调用者是如何释放返回给你的字符串的?我认为你应该这样做。