如何使用PyObject_CallObject查询复杂返回类型的数据?

时间:2014-06-04 15:59:12

标签: c++ python-3.x python-c-api

我有一个小的python程序来计算一个2d位置

def getPosition(lerpParameter):
    A = getClothoidConstant()
    ...

python脚本可以在我的项目文件夹here中找到。

函数getPosition包含在文件clothoid.py中。该函数返回Vector2类型的值。如何在我的C ++程序中访问返回的Vector2d的数据?

C ++程序如下所示:

    /// Get function
    PyObject  *pFunc = PyObject_GetAttrString(pModule, pid.functionName);
    // pFunc is a new reference

    if (pFunc && PyCallable_Check(pFunc)) 
    {
        PyObject *pArgs = PyTuple_New(pid.getArgumentCount());

        PyObject *pValue = nullptr;

        // setup function parameters
        for (int i = 0; i < pid.getArgumentCount(); ++i) 
        {
            if (pid.arguments[i].type == eType::Int)
            {
                pValue = PyLong_FromLong(atoi(pid.arguments[i].name.c_str()));
            }
            else
            {
                pValue = PyFloat_FromDouble(atof(pid.arguments[i].name.c_str()));
            }

            if (!pValue) 
            {
                Py_DECREF(pArgs);
                Py_DECREF(pModule);
                std::cout << "Cannot convert argument" << std::endl;
                throw std::runtime_error("Cannot convert argument");
            }
            // pValue reference stolen here:
            PyTuple_SetItem(pArgs, i, pValue);
        }

        pValue = PyObject_CallObject(pFunc, pArgs);
        Py_DECREF(pArgs);

        if (pValue != nullptr)
        {
            switch (pid.returnType)
            {
...

            case eType::Double:
                //std::cout << "Result of call: " << PyFloat_AsDouble(pValue) << std::endl;
                doubleValue_ = PyFloat_AsDouble(pValue);
                break;

            case  eType::Vector2d:
                {
                    // How can I acccess the data here?

                }
                break;

            default:
                break;
            }

            Py_DECREF(pValue);
        }

如果返回类型是double或int,则很容易获得相应的值。但我不知道如何访问Vector2的数据。

1 个答案:

答案 0 :(得分:1)

如果你想获得'x'属性,并且你知道它是一个浮点数:

PyObject *temp = PyObject_GetAttrString(pValue, "x");
if (temp == NULL) {
    // error handling
}
double x = PyFloat_AsDouble(temp);

// clean up reference when done with temp
Py_DECREF(temp);