Comments 13
У вас там неправильно разбираются аргументы в printString(): PyObject * args это всегда types.TupleType, и переданную при вызове строку оттуда надо доставать через PyArg_ParseTuple(), плюс возвращать что-то из такого метода — лишняя ненужна работа, можно просто делать Py_RETURN_NONE.
Хотя, у вас там тип метода опущен, и получается что это deprecated METH_OLDARGS, так что работать оно, конечно, будет, но плохо так делать совсем.
Спасибо, юный падаван.
Спасибо за все замечания, поправил код в соответствии с ними.
Вы неправильно поправили =)
1) Если PyArg_ParseTuple() не смог что-нибудь распарсить, потому что функции были переданые неверные параметры, то он возвращает false и бросает исключение, поэтому в этом месте из функции нужно выходить через return NULL, чтобы интерпретатор понял, что не всё прошло гладко. Проще говоря, возвращение NULL сообщает интерпретатору, что при вызове было брошено исключение и с ним надо что-то делать.
2) Спецификатор формата «s» означает const char *, а не std::string, тем более вот так вот писать в объект, вообще говоря, нельзя, потому что это его превратит в кровавое месиво. Плюс, совсем не обязательно объявлять переменную для строки статично в namespace scope.
3) Просто так возвращать Py_None нельзя, это такой же питонячий объект как и все остальные, ему тоже надо делать Py_INCREF(). Но, поскольку возвращение None это идиоматическое действие, есть макрос Py_RETURN_NONE(), который за вас всё сделает сам.
Вот так будет правильно:
1) Если PyArg_ParseTuple() не смог что-нибудь распарсить, потому что функции были переданые неверные параметры, то он возвращает false и бросает исключение, поэтому в этом месте из функции нужно выходить через return NULL, чтобы интерпретатор понял, что не всё прошло гладко. Проще говоря, возвращение NULL сообщает интерпретатору, что при вызове было брошено исключение и с ним надо что-то делать.
2) Спецификатор формата «s» означает const char *, а не std::string, тем более вот так вот писать в объект, вообще говоря, нельзя, потому что это его превратит в кровавое месиво. Плюс, совсем не обязательно объявлять переменную для строки статично в namespace scope.
3) Просто так возвращать Py_None нельзя, это такой же питонячий объект как и все остальные, ему тоже надо делать Py_INCREF(). Но, поскольку возвращение None это идиоматическое действие, есть макрос Py_RETURN_NONE(), который за вас всё сделает сам.
Вот так будет правильно:
static PyObject *
printString(PyObject * self, PyObject* args)
{
const char * toPrint;
if(!PyArg_ParseTuple(args, "s", &toPrint))
{
return NULL;
}
std::cout << toPrint << std::endl;
Py_RETURN_NONE;
}
Мне одному кажется, что тема статьи раскрыта во втором абзаце, а остальное немного лишнее?
Зачем вы возвращаете пустую строку из ф-ии printString? return Py_BuildValue("");
У вас однопоточное приложение?
Sign up to leave a comment.
Интеграция Python и C++