Python C ++ api - возвращает различные типы при перегрузке функций - PullRequest
0 голосов
/ 17 мая 2019

У меня есть класс C ++, который содержит два перегруженных метода sayHi () , каждый с различным типом возвращаемого значения:

class Box {
   public:

      Box();

      void sayHi(char *name);

      int sayHi(int number);

};

Когда я пытался обернуть эти функции, я следовалпредложение ShadowRanger и "написать одну функцию-обертку, которая проверяет предоставленный аргумент и отправляет правильную" настоящую "функцию" .

Вот оно:

static PyObject *pyBox_sayHi_char(PyBox *self, char *Name)
{
    self->bx->sayHi(Name);

    Py_RETURN_NONE;
}

static int *pyBox_sayHi_int(PyBox *self,  int number)
{
    int answer;

    answer = self->bx->sayHi(number);

    return answer;
}

static PyObject *Hi_overload_switch(PyBox *self,  PyObject *args)
{
    PyObject *x;

    if (!PyArg_ParseTuple(args, "O", &x))
        return NULL;

    if (PyUnicode_Check(x))
    {
        const char* s = PyBytes_AsString(PyUnicode_AsUTF8String(x)); // convert PyObject to char*

        Py_DECREF(x);

        return pyBox_sayHi_char(self, s);
    }
    if (PyLong_Check(x))
    {   
        return pyBox_sayHi_int( self, PyLong_AsLong(x) );
    }
    Py_RETURN_NOTIMPLEMENTED;
}

и следующая таблица методов:

static PyMethodDef pyBox_methods[] = {
    {"Hi", (PyCFunction)Hi_overload_switch, METH_VARARGS, "Hi"},
    {NULL, NULL, 0, NULL}
};

Однако я получаю сообщение об ошибке:

error: cannot convert ‘int*’ to ‘PyObject*’ {aka ‘_object*’} in return
         return pyBox_sayHi_int( self, PyLong_AsLong(x) );

AFAIK, я не хочу преобразовыватьвозвращать типы в PyObjects, поскольку перегруженным методам может потребоваться возвращать пользовательские типы.Поэтому int vs void в моем примере только для иллюстрации - я вполне мог бы написать PyBanana vs PyOrange типов данных.

У меня вопрос, как сделать так, чтобы функция Hi_overload_switch возвращала различные типы?

Спасибо!

1 Ответ

1 голос
/ 17 мая 2019

Вам необходимо вернуть Python int. В источнике C / C ++ это PyLongObject (который является подтипом PyObject, поэтому вы можете привести PyLongObject* к PyObject* и обратно). Чтобы преобразовать C ++ int в PyObject* Python int, используйте PyObject* PyLong_FromLong(long):

static PyObject *pyBox_sayHi_int(PyBox *self,  int number)
{
    int answer;

    answer = self->bx->sayHi(number);

    return PyLong_FromLong(answer);
}
...