使用ctypes从C结构构造numpy数组。ValueError:“<P”不是有效的PEP 3118缓冲区格式字符串

2024-05-06 02:09:41 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑下面的代码:

参考文献h

typedef struct OutPutImage{
    double *** output_img;
    int nb_images;
    int nb_cols;
    int nb_rows;
}opi_;

void test_output_images(struct OutPutImage * out, int nb_images, int nb_cols, int nb_rows);

参考文献c

#include <stdlib.h>
#include "by_ref.h"

void test_output_images(struct OutPutImage* out, int nb_images, int nb_cols, int nb_rows){
    out->nb_images = nb_images;
    out->nb_cols = nb_cols;
    out->nb_rows = nb_rows;

    out->output_img = (double***)malloc((nb_images) * sizeof(double**));
    for(int i = 0; i < nb_images; i++){
        out->output_img[i] = (double**)malloc((nb_cols) * sizeof(double*));
        for(int j = 0; j < nb_cols; j++){
            out->output_img[i][j] = (double*)malloc((nb_rows) * sizeof(double));
            for(int k = 0; k < nb_rows; k++){
                out->output_img[i][j][k] = 0;
            } 
        }
    }
}

由_ref.py提供

import ctypes
import numpy.ctypeslib as npct
import numpy as np

class OutPutImage(ctypes.Structure):

    _fields_ = [('output_img', npct.ndpointer(dtype=np.double, ndim=3)), 
                ('nb_images', ctypes.c_int), 
                ('nb_cols', ctypes.c_int),
                ('nb_rows', ctypes.c_int)]

    _libc = ctypes.CDLL("./by_ref.so")

    def __init__(self, nb_images=None, nb_cols=None, nb_rows=None):
        self.nb_images = nb_images
        self.nb_cols = nb_cols
        self.nb_rows = nb_rows

if __name__ == '__main__':
    libc_adm = ctypes.CDLL("./by_ref.so")
    libc_adm.test_output_images.restype = ctypes.c_int
    libc_adm.test_output_images.argtypes = [ctypes.POINTER(OutPutImage), ctypes.c_int,
                                            ctypes.c_int, ctypes.c_int]

    output_image = OutPutImage(1, 2, 3)
    libc_adm.test_output_images(ctypes.byref(output_image), 4, 5, 6)  
    print(np.array(output_image.output_img, dtype=np.float))    # error ocures here

当我使用以下生成文件生成并运行此代码时

by_ref: by_ref.so
    python by_ref.py

by_ref.so: by_ref.o
    gcc -shared -o by_ref.so by_ref.o

by_ref.o: by_ref.c
    gcc -c -Wall -fpic by_ref.c -o by_ref.o

我得到一个错误:

Traceback (most recent call last):
  File "by_ref.py", line 46, in <module>
    print(np.array(output_image.output_img, dtype=np.float))
ValueError: '<P' is not a valid PEP 3118 buffer format string
make: *** [Makefile:2: by_ref] Error 1

我确信test_output_images正在做它应该做的事情。但是,我无法从结构中的数据构建numpy数组。我如何做到这一点?还有,我什么时候释放内存? 谢谢

编辑:

如果我使用np.ctypeslib.as_array(output_image.output_img),我会得到相同的错误:

ValueError: '<P' is not a valid PEP 3118 buffer format string

更新:

如果我使用x = np.ctypeslib.as_array(( ctypes.c_double*array_length ).from_address( ctypes.addressof(output_image.output_img) )),其中array_length=nb_images*nb_cols*nb_rows,那么我可以避免上述错误,但是新的数组x包含垃圾,无法对其进行整形


Tags: testrefimgoutputbynpoutctypes