如何在C API中创建一个Python字节对象

6
我有一个Numpy布尔向量,并尝试使用C API尽快从中获取一个字节对象。(理想情况下,我希望将向量的二进制值映射到字节对象。)
我可以成功读取向量,并将数据存储在bool_vec_arr中。我考虑创建一个整数并以如下方式设置其位:
PyBytesObject * pbo; 
int byte = 0;
int i = 0;
while ( i < vec->dimensions[0] )  
{
    if ( bool_vec_arr[i] )
    {
        byte |= 1UL << i % 8;
    }
    i++;
    if (i % 8 == 0)
    {
        /* do something here? */
        byte = 0;
    }
}
return PyBuildValue("S", pbo); 

但我不确定如何使用 pbo 中的 byte 值。是否有任何建议?


附注:return PyBuildValue("S", pbo); 没有意义,只会导致引用泄漏(它增加了 pbo 的引用计数并返回它,而它本身没有任何改变,但你必须支付解析格式字符串的开销)。你应该直接执行 return pbo;,或者如果你已经在其他地方存储了 pbo 的副本以便不能放弃自己的引用,那么在 return pbo; 之前应该执行 Py_INCREF(pbo); - ShadowRanger
1个回答

5

你需要存储你刚刚完成的字节。你的问题是你还没有创建一个实际的bytes对象来填充,所以请先创建。你知道结果必须有多长(布尔向量的大小除以8并向上取整),因此请使用PyBytes_FromStringAndSize获取正确大小的bytes对象,然后在进行过程中填充。

你可以使用以下方式分配:

// Preallocate enough bytes
PyBytesObject *pbo = PyBytes_FromStringAndSize(NULL, (vec->dimensions[0] + 7) / 8);
// Put check for NULL here

// Extract pointer to underlying buffer
char *bytebuffer = PyBytes_AsString(pbo);

在处理 IT 技术相关内容时,需要将数字加 7 再除以 8 后向上取整来确保足够的字节数用于存储所有位,并在完成一个字节后将其分配给适当的索引,例如:

if (i % 8 == 0)
{
    bytebuffer[i / 8 - 1] = byte;  // Store completed byte to next index
    byte = 0;
}

如果最后一个字节可能不完整,您需要决定如何处理此情况(填充位出现在左边还是右边,最后一个字节是否被省略,因此您不应该将分配四舍五入等)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接