【问题标题】:Py_BuildValue and PyArg_ParseTuple Seg faultPy_BuildValue 和 PyArg_ParseTuple Seg 错误
【发布时间】:2015-11-10 22:52:28
【问题描述】:

编辑:我在流程开始时错过了Py_Initialize()

我在使用 Py_BuildValue 和 PYArg_ParseTuple 时遇到了一些奇怪的行为。

首先,每当我尝试构建一个整数时,我都会在 Py_BuildValue 处遇到一个段错误。 浮点数、对象或字符串不会发生这种情况。

其次,当我试图解析一个元组时,我也会得到一个段错误,除非我正在解析一个包含单个字符串:“s”或单个 PyObject:“O”的元组。 (如果我尝试同时解析两者,我也会遇到段错误:“Os”)

这里有两个段错误的例子:

#include <Python.h>
#include <iostream>

using namespace std;

int main() {
    Py_Initialize(); // <-- Missing this
    PyObject* pString = Py_BuildValue("s", "hello"); //<- Works fine
    PyObject* pFloat = Py_BuildValue("f", 2.3); //<- Works fine

    PyObject* pInt = Py_BuildValue("i", 2); // <- Seg faults

    return 0;
}

还有一个 ParseTuple 示例(针对正确的构建值和 api 调用测试进行了编辑):

#include <Python.h>
#include <iostream>

using namespace std;

int main() {
    Py_Initialize(); // <-- Missing this
    PyObject* pFloat = Py_BuildValue("f", 2.3);
    if(!pFloat)
        cout << "Error Float" << endl;

    PyObject *pTuple = PyTuple_New(1);
    if(!pTuple)
        cout << "Error Creating Tuple" << endl;

    if(PyTuple_SetItem(pTuple, 0, pFloat)) //Returns 0 on success
        cout << "Error Set Item" << endl;

    // parse tuple items
    float f;
    if(!PyArg_ParseTuple(pTuple, "f", &f))
        PyErr_SetString(PyExc_TypeError, "invalid parameter");

    return 0;
}

我正在使用 anaconda python 2.7 在 RedHat 上运行

我编译:

g++ `python-config --cflags` -L/home/user/anaconda/lib/ -lpython2.7 test.cpp -o test.out

使用 anaconda python 可能有问题吗?我已将问题分解为我能想到的最简单的情况......

【问题讨论】:

  • 不正确"2.3"改为2.3会发生什么? ("f" 格式需要 double 而不是字符串!)。
  • 是的,它仍然在 ParseTuple 行出现段错误。

标签: python c++


【解决方案1】:

我发现了几个问题。

Py_BuildValuef 选项从 C/C++ double 构造 Python 浮点数。你传递了一个字符串,而不是一个双精度。

每次调用 Python C-API 函数后,您需要测试返回值以查看是否发生错误。这需要在每次通话后完成。

编辑 - 又一期。

将 Python C-API 调用嵌入到 C/C++ 程序中时,需要通过调用 Py_Initialize() 来初始化解释器。

【讨论】:

  • 感谢您的回复,我进行了更改。我复制和粘贴太多,忘记从 2.3 中删除引号。我编辑了上面的代码,但它仍然在 ParseTuple 行出现段错误......我还编译了 python 的本地副本以从等式中删除 anaconda。
  • 您还需要添加对Py_Initialize()的调用。我已经编辑了答案。
  • 你是对的!那解决了它。不幸的是,网上有成千上万的小教程,但似乎没有一个提到这一点。当然,我猜大多数人都假设你是从 python 调用这些函数,所以你不需要初始化解释器(对吗?)。感谢您的帮助。
  • 你是对的。我(可能还有大多数用户)编写由 Python 调用的 C/C++。有关将 Python 嵌入 C/C++ 的文档,请参阅 docs.python.org/2/extending/embedding.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-11
  • 2012-05-08
  • 1970-01-01
  • 1970-01-01
  • 2018-10-03
相关资源
最近更新 更多