Как создать объект байтов Python в C API - PullRequest
2 голосов
/ 27 апреля 2019

У меня есть вектор Numpy bool s, и я пытаюсь использовать C API, чтобы получить объект bytes как можно быстрее из него. (В идеале я хочу отобразить двоичное значение вектора на объект байтов.)

Я могу успешно прочитать вектор, и у меня есть данные в bool_vec_arr. Я думал о создании int и установке его битов таким образом:

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. У кого-нибудь есть предложения?

1 Ответ

2 голосов
/ 27 апреля 2019

Вам необходимо сохранить только что завершенный байт.Ваша проблема в том, что вы не создали фактический bytes объект для заполнения, так что сделайте это.Вы знаете, как долго должен получиться результат (одна восьмая размера вектора bool, округленный в большую сторону), поэтому используйте 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);

, где добавление 7, затем деление на 8 округлений, чтобы убедиться, что у вас достаточно байтов для всех битов, а затем присвоение соответствующиминдекс, когда вы закончили байт, например:

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

Если последний байт может быть неполным, вам нужно решить, как с этим справиться (появляются биты пэда слева или справа,последний опущенный байт, поэтому вам не следует округлять распределение и т. д.).

...