C++ 嵌入 Python 时 PyArg_ParseTuple 解析字符串参数失败

4 投票
1 回答
6260 浏览
提问于 2025-04-16 22:26

我正在尝试在一个OpenGL/SDL应用程序中添加嵌入式Python。目前为止,一切都运行得很好,比如通过SDL键盘事件输入字符串,并用嵌入的Python解释器执行它。现在我想添加一些函数,以便调用C/C++函数,比如

void set_iterations(int c);

这个函数在Python解释器中被调用,使用的是

>>> test.iterations(23)

整数参数的解析工作得很好

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',)


解决方案: rodrigo指出的错误,最初让我相信我的调试代码有问题,应该打印出结果字符串作为PyObject。但问题在于我传递给解析器的指针是错误的,导致内存中出现未定义的行为,因此让我误以为解析器有问题。最后出现的解析器错误实际上是调试输出本身,指向了错误的内存地址。感谢rodrigo,因为你的回答帮助我解决了这个问题:我接受了。谢谢你的帮助和耐心。

1 个回答

3

试试这个:

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
}

撰写回答