C ++ встроенный Python PyArg_ParseTuple завершается ошибкой со строковыми аргументами - PullRequest
2 голосов
/ 28 июля 2011

Я пытаюсь добавить встроенный python в приложение OpenGL / SDL.Пока все работает нормально, например, ввод строки через события клавиатуры SDL и выполнение ее с помощью встроенного интерпретатора Python.Теперь я добавляю функции для вызова функций C / C ++, например,

void set_iterations(int c);

вызывается в интерпретаторе python с помощью

>>> test.iterations(23)

Разбор целочисленного параметра работает как charm

static PyObject* test_iterations(PyObject *self, PyObject *args) {  
    int iterations;
    PyArg_ParseTuple(args,"i",&iterations);
    set_iterations(iterations);

    return Py_None;
}

Но когда я пытаюсь это сделать: >>> test.addignore('something')

static PyObject* test_addignore(PyObject *self, PyObject *args) {

        char* ignorestring;
        //PyArg_ParseTuple(args,"s",ignorestring);
        PyArg_ParseTuple(args,"s",&ignorestring);
        add_global_ignore(ignorestring); // C function

        return Py_None;
}

Python выдает мне эту ошибку:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-3: invalid data

Строка должна быть UTF-8, как SDLнастроен на захват UNICODE с клавиатуры, а все остальное работает отлично.

Кто-нибудь имеет представление о том, что я могу делать здесь неправильно?

Я также проверял объект args, передаваемый вфункция с

std::string args_str;

PyObject* repr = PyObject_Repr(args);
if (repr != NULL) {
    args_str = PyBytes_AsString(PyUnicode_AsEncodedString(repr, "utf-8", "Error"));
    Py_DECREF(repr);
}
std::cout << args_str << "\n";

И это дает мне следующее: ('somestring',)


Решение: Ошибка, указанная Родриго, изначально заставляла поверить, что мой код отладки, который должен напечататьполученная строка как PyObject была неправильной.Но проблема заключалась в том, что я передавал парсеру неправильный указатель, что приводило к неопределенному поведению в памяти и, следовательно, заставляло меня полагать, что парсер был проблемой.Происходящей последней ошибкой синтаксического анализатора был сам вывод отладки, который указывал на неправильный адрес памяти.Спасибо Родриго, так как ваш ответ приведет к решению проблемы: принято.Спасибо за вашу помощь и терпение.

1 Ответ

3 голосов
/ 28 июля 2011

Попробуйте:

static PyObject* test_addignore(PyObject *self, PyObject *args) {
    char* ignorestring;
    if (!PyArg_ParseTuple(args,"s", &ignorestring)) //Note the &
        return NULL;                                //Never ignore errors
    add_global_ignore(ignorestring);

    Py_RETURN_NONE;  //Always use helper macros
}
...