首页 > 解决方案 > 使用 PyArg_ParseTuple 时第一个参数错误

问题描述

我为 ac 扩展类型编写方法:

static PyObject *
RawGraphState_apply_C_L(RawGraphState * self
                        , PyObject * args)
{
    npy_uint8 vop = 0xdeadbeef;
    npy_intp i;// = 0xdeadbeef;

    if(!PyArg_ParseTuple(args, "II", &i, &vop))
    {
        return NULL;
    }

    printf("i = %ld\n", i);

    if(vop >= 24)
    {
        PyErr_SetString(PyExc_ValueError, "vop index must be in [0, 23]");
        return NULL;
    }

    if(i >= self->length)
    {
        PyErr_SetString(PyExc_ValueError, "qbit index out of range");
        return NULL;
    }

    printf("mapping vop[%ld] %d,%d -> %d\n", i, vop, self->vops[i], vop_lookup_table[vop][self->vops[i]]);
    self->vops[i] = vop_lookup_table[vop][self->vops[i]];

    Py_RETURN_NONE;

}

但是,这不能正确读取第一个参数。它要么默认为 0,要么默认为一个巨大的数字(取决于我调用方法 inpytest或 using ipython):

In [1]: from pyqcs.graph.backend.raw_state import RawGraphState                                                                        
^[[A
In [2]: g = RawGraphState(2)                                                                                                           

In [3]: g.apply_C_L(1, 0)                                                                                                              
i = 140200617443328
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-57081093fbb3> in <module>
----> 1 g.apply_C_L(1, 0)

ValueError: qbit index out of range

我在这里做错了什么?

--

你可以在这里找到代码:

https://github.com/daknuett/PyQCS/blob/graph_simulation/src/pyqcs/graph/backend/raw_state.c

从第 300 行开始。

标签: pythonpython-3.xpython-c-api

解决方案


格式代码I需要传递一个指向unsigned int. 不是一个npy_uint8或一个npy_intp。一个unsigned int且只有一个unsigned intuint像is 一样的 8 位vop绝对是错误的大小,因为尝试将其写入就好像它是正常的一样unsigned int可能会覆盖其他一些数据。Anpy_intp可能是也可能不是正确的大小,但由于它可能是错误的,所以不要使用它。

对于您想要的第一个参数bor B,它是一个无符号字符(几乎每个平台上都有 8 位)。阅读文档以了解差异。对于第二个参数可能要使用Kfor an unsigned long long,传递给它 an unsigned long long(应该足够大......),然后将其转换npy_intp为自己检查溢出。或者,您可以使用Othen 调用PyLong_AsVoidPtr它来获取 C 的号码。

顺便说一句:npy_uint8 vop = 0xdeadbeef;应该可能会产生警告,因为该数字不适合 8 位。


推荐阅读