我正在尝试重载以下 sayHi 函数,该函数旨在接收char *作为输入参数,或者, 或者,一个char *和一个整数。
它是 Box 类的一部分(它本身用于定义python对象 PyBox ):
class Box {
public:
Box();
void sayHi(char *name);
void sayHi(char *name, int number);
};
在包装程序中,我定义了以下方法:
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}
};
但是,当我使用python 3.7并运行时:
bo.Hi("John", 52364)
bo.Hi("Steve")
它输出第一个语句,但在Steve上出现段错误。有什么建议为什么会这样?
谢谢!
答案 0 :(得分:1)
问题在这里:
if (!PyArg_ParseTuple(args, "|OO", &x, &y))
return NULL;
if (PyUnicode_Check(x) && PyLong_Check(y)) ...
您要使用两个可选参数(如果没有给出参数,PyArg_ParseTuple不会修改传递的变量)。因此bo.Hi("Steve")
仅填充x,但是随后您使用y而不检查它,因此出现段错误。您一定已经很幸运使用y的初始值的早期版本。
答案 1 :(得分:0)
这可以解决问题(请参阅@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;
}