gpt4 book ai didi

python - PyArg_ParseTupleAndKeywords() 中的 None 值 PyObject 为 NULL

转载 作者:太空宇宙 更新时间:2023-11-03 23:29:48 24 4
gpt4 key购买 nike

我正在将扩展类型对象传递给 Python 函数,它需要将此类型的变量传递给 C 函数。我的扩展类型如下所示:

typedef struct {
PyObject_HEAD
rec_rset_t rst; //need to pass this to C function
} RSet;

rec_rset_t 是一个指向结构的指针,如下所示:

typedef struct rec_rset_s *rec_rset_t;

rec_rset_s 的定义如下:

struct rec_rset_s
{
size_t size;
int a,b;
}

所以我有一个 Python 扩展函数,它接收一个 RSet 对象作为参数。

static PyObject*
Recon_query(Recon *self, PyObject *args, PyObject *kwds)
{
const char *type;
RSet *tmp = PyObject_NEW(RSet, &RSetType);
rec_rset_t res;
static char *kwlist[] = {"type", "rset", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kwds, "zO", kwlist,
&type, &rset))
{
return NULL;
}
res = cquery(self->rcn, type, rset->rst);
tmp->rst = res;
return Py_BuildValue("O",tmp);
}

问题是我希望能够为 RSet 对象传递 None,并让它在 C 中转换为 NULL 以及变量 rst 为 NULL。如果我通过 None,我会得到一个段错误,因为 PyArg_ParseTupleAndKeywords“O” 选项不处理 PyObject 的 None 值(这与 "s" 选项不同,如果我们传递一个 NULL 字符串,我们可以在其中使用 "z") .我尝试手动检查 Py_None 对象,但没有成功。所以目前我正在做一些不太优雅的事情,像这样:

if(rset->rst == 0x89e8a0)
rset->rst = NULL;

因为那是当我传递 Nonerset->rst 的值,然后将此 rset->rst 传递给 cquery 函数。如何在接收扩展类型对象时将 None 值传递给 PyArg_ParseTuple?有没有一种通用的方法可以做到这一点?

编辑:

我错误地检查了 Py_None 的 rset->rst 的值。检查

if((PyObject *)rset == Py_None)

计算结果为真,所以是的,没有被处理。但是值 rset->rst(我传递给 cquery)不是 NULL,这正是我想要的。手动设置 rset->rst = NULL 是唯一的方法吗?

最佳答案

问题在于,如果 rset 设置为 Py_None(一个 PyObject*),则只有 PyObject_HEAD 定义的字段保证有效;本质上你已经得到了一个指向不是 RSet 的东西的指针。

与其将 rset->rst 设置为 NULL(如果 rset == Py_None,可能会修改不应该修改的内存),您应该修改代码,使其最初引用 PyObject*,然后仅引用一旦确定它不是 Py_None 就转换为 RSet*:

PyObject *rsetobj = NULL;
rec_rset_t rst;
if (! PyArg_ParseTupleAndKeywords(args, kwds, "zO", kwlist,
&type, &rsetobj))
{
return NULL;
}
if (rsetobj == Py_None)
rst = NULL;
else
rst = ((RSet*)rsetobj)->rst;
res = cquery(self->rcn, type, rst);

您可能还想在转换为 RSet 之前明确检查对象类型。 (或者使用 O!,它会为您进行类型验证,但我似乎记得它不允许使用 None,而在这种情况下您需要它。)

关于python - PyArg_ParseTupleAndKeywords() 中的 None 值 PyObject 为 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18570769/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com