[英]Construct a numpy array from a C structure using ctypes. ValueError: '<P' is not a valid PEP 3118 buffer format string
Consider the following code:考虑以下代码:
by_ref.h by_ref.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);
by_ref.c by_ref.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;
}
}
}
}
and和
by_ref.py by_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
When I make and run this code using the following Makefile当我使用以下 Makefile 制作并运行此代码时
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
I get the error:我得到错误:
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
I am sure test_output_images
is doing what it is supposed to do.我确信
test_output_images
正在做它应该做的事情。 However I can't build the numpy array from the data in the structure.但是我无法从结构中的数据构建 numpy 数组。 How do I accomplish this?
我该如何做到这一点? Also, when do I free the memory?
另外,我什么时候释放 memory? Thanks.
谢谢。
Edit:编辑:
If I use np.ctypeslib.as_array(output_image.output_img)
I get the same error:如果我使用
np.ctypeslib.as_array(output_image.output_img)
我得到同样的错误:
ValueError: '<P' is not a valid PEP 3118 buffer format string
Update:更新:
If I use x = np.ctypeslib.as_array(( ctypes.c_double*array_length ).from_address( ctypes.addressof(output_image.output_img) ))
, where array_length=nb_images*nb_cols*nb_rows
, then I avoid the error described above, but the new array x contains garbage and it can't be reshaped.如果我使用
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 包含垃圾,无法重塑。
It's a bug in NumPy 1.15.x.这是 NumPy 1.15.x 中的一个错误。 Either downgrade to 1.14.6 or older, or upgrade to 1.16.0 or newer.
降级到 1.14.6 或更早版本,或者升级到 1.16.0 或更高版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.