【问题标题】:Parsing unsigned ints (uint32_t) in python's C api在python的C api中解析无符号整数(uint32_t)
【发布时间】:2015-09-29 01:24:30
【问题描述】:

如果我编写一个接受单个无符号整数 (0 - 0xFFFFFFFF) 的函数,我可以使用:

uint32_t myInt;
if(!PyArg_ParseTuple(args, "I", &myInt))
    return NULL;

然后从 python,我可以传递 intlong

但是如果我得到一个整数列表呢?

uint32_t* myInts;
PyObject* pyMyInts;
PyArg_ParseTuple(args, "O", &pyMyInts);

if (PyList_Check(intsObj)) {
    size_t n = PyList_Size(v);
    myInts = calloc(n, sizeof(*myInts));

    for(size_t i = 0; i < n; i++) {
        PyObject* item = PyList_GetItem(pyMyInts, i);

        // What function do I want here?
        if(!GetAUInt(item, &myInts[i]))
            return NULL;
    }
}

// cleanup calloc'd array on exit, etc

具体来说,我的问题是处理:

  • 包含ints 和longs 混合的列表
  • 分配给 uint32 时检测溢出

【问题讨论】:

    标签: python c python-2.x cpython


    【解决方案1】:

    您可以创建一个元组并使用与单个参数相同的方法。在 C 端,元组对象并不是真正不可变的,所以不会有太大的麻烦。

    PyLong_AsUnsignedLong 也可以为您工作。它接受 int 和 long 对象,否则会引发错误。但如果sizeof(long) 大于 4,您可能需要自己检查上限溢出。

    static int 
    GetAUInt(PyObject *pylong, uint32_t *myint) {
        static unsigned long MAX = 0xffffffff;
        unsigned long l = PyLong_AsUnsignedLong(pylong);
    
        if (l == -1 && PyErr_Occurred() || l > MAX) {
            PyErr_SetString(PyExc_OverflowError, "can't convert to uint32_t");
            return false;
        }
    
        *myint = (uint32_t) l;
        return true;
    }
    

    【讨论】:

    • 有没有办法返回 false 并清除错误? (我需要检查多种类型的参数)
    • @Eric 只需致电PyErr_Clear()。就这么说吧,因为您在代码中返回了NULL
    猜你喜欢
    • 1970-01-01
    • 2019-08-11
    • 2011-04-28
    • 1970-01-01
    • 2021-05-27
    • 2011-12-22
    • 1970-01-01
    • 2016-09-24
    • 2015-01-25
    相关资源
    最近更新 更多