[英]Python C++ API - overloading functions with variable number of arguments
I am trying to overload the following sayHi function, that is meant to receive a char* as input argument, or, alternatively, a char* and an integer. 我正在尝试重载以下sayHi函数,该函数旨在接收char *作为输入参数,或者接收char *和一个整数。
It is part of class Box (which itself is used to define the python object PyBox ): 它是Box类的一部分(它本身用于定义python对象PyBox ):
class Box {
public:
Box();
void sayHi(char *name);
void sayHi(char *name, int number);
};
In my wrapper, I have defined the following methods: 在包装器中,我定义了以下方法:
static PyObject *pyBox_sayHi_char(PyBox *self, char *Name)
{
self->bx->sayHi(Name);
Py_RETURN_NONE;
}
static PyObject *pyBox_sayHi_char_int(PyBox *self, char *Name, int number)
{
self->bx->sayHi(Name, number);
Py_RETURN_NONE;
}
static PyObject *Hi_overload_switch(PyBox *self, PyObject *args)
{
PyObject *x = NULL;
PyObject *y = NULL;
if (!PyArg_ParseTuple(args, "|OO", &x, &y))
return NULL;
if (PyUnicode_Check(x) && PyLong_Check(y) && y != NULL)
{
printf("A!\n\n");
const char* s = PyBytes_AsString(PyUnicode_AsUTF8String(x));
Py_DECREF(x);
return pyBox_sayHi_char_int(self, s, PyLong_AsLong(y));
}
else if (PyUnicode_Check(x) && y == NULL)
{
printf("B!\n\n");
const char* s = PyBytes_AsString(PyUnicode_AsUTF8String(x));
Py_DECREF(x);
return pyBox_sayHi_char(self, s);
}
else
{
Py_RETURN_NOTIMPLEMENTED;
}
Py_RETURN_NOTIMPLEMENTED;
}
static PyMethodDef pyBox_methods[] = {
{"Hi", (PyCFunction)Hi_overload_switch, METH_VARARGS, "Hi"},
{NULL, NULL, 0, NULL}
};
However, when I go to python 3.7 and I run: 但是,当我转到python 3.7并运行时:
bo.Hi("John", 52364)
bo.Hi("Steve")
it prints the first statement but segfaults on Steve. 它输出第一个语句,但在Steve上出现段错误。 Any suggestions why this is the case?
有什么建议为什么会这样?
Thanks! 谢谢!
Problem is here: 问题在这里:
if (!PyArg_ParseTuple(args, "|OO", &x, &y))
return NULL;
if (PyUnicode_Check(x) && PyLong_Check(y)) ...
You're taking two optional parameters (PyArg_ParseTuple does not modify the passed variables if no parameter is given). 您将使用两个可选参数(如果没有给出参数,PyArg_ParseTuple不会修改传递的变量)。 So
bo.Hi("Steve")
only populates x, but then you use y without checking it, thus the segfault. 因此
bo.Hi("Steve")
仅填充x,但是随后您使用y而不检查它,因此出现了段错误。 You must have been getting lucky with previous versions on the initial value of y. 您一定已经对使用y的初始值的早期版本感到幸运。
This fixes the issue (see answer by @gct to understand why): 这可以解决问题(请参阅@gct的答案以了解原因):
static PyObject *Hi_overload_switch(PyBox *self, PyObject *args)
{
PyObject *x = Py_None;
PyObject *y = Py_None;
if (!PyArg_ParseTuple(args, "|OO", &x, &y))
{return NULL;}
if (PyUnicode_Check(x) && PyLong_Check(y) && y != Py_None)
{
printf("A!\n\n");
char* s = PyBytes_AsString(PyUnicode_AsUTF8String(x));
Py_DECREF(x);
return pyBox_sayHi_char_int(self, s, PyLong_AsLong(y));
}
else if (PyUnicode_Check(x) && y == Py_None)
{
printf("B!\n\n");
char* s = PyBytes_AsString(PyUnicode_AsUTF8String(x));
Py_DECREF(x);
return pyBox_sayHi_char(self, s);
}
else
{
Py_RETURN_NOTIMPLEMENTED;
}
Py_RETURN_NOTIMPLEMENTED;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.