Python 在C结构中保存numpy数组
我使用ctypes将numpy数组传递给C代码。我希望将这些信息保存在C结构中。我有以下C代码: 我的文件.hPython 在C结构中保存numpy数组,python,c,numpy,ctypes,Python,C,Numpy,Ctypes,我使用ctypes将numpy数组传递给C代码。我希望将这些信息保存在C结构中。我有以下C代码: 我的文件.h typedef结构容器 { int nb_行; int nb_cols; 双**数据; }; void save_d2_double(int nb_行、int nb_列、double*数据[nb_列]); 无效打印容器(); 我的文件.c #包括 #包括“my_file.h” 结构容器c; void save_d2_double(int nb_行、int nb_列、double*数据
typedef结构容器
{
int nb_行;
int nb_cols;
双**数据;
};
void save_d2_double(int nb_行、int nb_列、double*数据[nb_列]);
无效打印容器();
我的文件.c
#包括
#包括“my_file.h”
结构容器c;
void save_d2_double(int nb_行、int nb_列、double*数据[nb_列]){
c、 nb_行=nb_行;
c、 nb_cols=nb_cols;
c、 数据=数据;
}
无效打印容器(){
printf(“\n”);
printf(“%d\t%d”,c.nb\u行,c.nb\u列);
对于(int i=0;i
以及python中的以下内容:
my_file.py
将numpy导入为np
将numpy.ctypeslib作为npct导入
导入ctypes
LIBC=ctypes.CDLL(“my_file.so”)
数组\u 2d\u double=npct.ndpointer(dtype=np.double,ndim=2)
LIBC.save\u d2\u double.restype=None
LIBC.save_d2_double.argtypes=[ctypes.c_int,ctypes.c_int,array_2d_double]
LIBC.print_container.restype=None
LIBC.print_container.argtypes=[]
#此数组的形状在最终应用程序中有所不同。
x_2d_d=np.数组([1,2,3,10.],[4,5,6,11.],[7,8,9,12.],dtype=np.64)
形状=x_2d_d形状
LIBC.save_d2_double(形状[0],形状[1],x_2d_d)
LIBC.print_容器()
当我想访问c.data
时,我得到:
分段故障(堆芯转储)
我怀疑问题出在double**数据的声明中但是,由于C事先不知道numpy数组的维度,我不知道如何声明这个字段
提前谢谢 第一个问题:double*data[nb\u cols]
是一个指针数组,或者相当于一个双指针,但这不是Python传递的内容。Python正在传递一个2D数组,或者相当于一个指向数组的指针,因此您的函数应该采用double(*data)[nb\u cols]
第二个问题:C不允许在结构中存储指向VLA的指针。您尝试改用双指针,但双指针与指向数组的指针不兼容。但是,有一个解决方案:由于数组是连续的,因此可以将指针视为指向第一个元素的指针,然后将其转换为指向使用它的函数中的VLA的指针(或者手动转换索引)
my_file.h:
struct容器
{
int nb_行;
int nb_cols;
双*数据;
};
void save_d2_double(int nb_行、int nb_列、double*数据);/*或双(*数据)[nb_cols]*/
作废打印容器(作废);
my_file.c:
#include <stdio.h>
#include "my_file.h"
struct container c;
void save_d2_double(int nb_rows, int nb_cols, double *data) { /* or double (*data)[nb_cols] */
c.nb_rows = nb_rows;
c.nb_cols = nb_cols;
c.data = data;
}
void print_container(void) {
double (*data)[c.nb_cols] = (double (*)[c.nb_cols])c.data; /* optional; see below */
printf("\n");
printf("%d\t%d", c.nb_rows, c.nb_cols);
for(int i = 0; i < c.nb_rows; i++) {
for(int j = 0; j < c.nb_cols; j++) {
printf("%f\t", data[i][j]); /* or c.data[i * c.nb_cols + j] */
}
printf("\n");
}
printf("\n");
}
#包括
#包括“my_file.h”
结构容器c;
void save_d2_double(int nb_行、int nb_列、double*数据){/*或double(*数据)[nb_列]*/
c、 nb_行=nb_行;
c、 nb_cols=nb_cols;
c、 数据=数据;
}
作废打印容器(作废){
双(*数据)[c.nb_cols]=(双(*)[c.nb_cols])c.data;/*可选;见下文*/
printf(“\n”);
printf(“%d\t%d”,c.nb\u行,c.nb\u列);
对于(int i=0;i
@Joseph Sible让Monica复职,你以前帮我解决了questinos关于ctypes的问题。你对此有什么建议吗?亲爱的@Joseph Sible,你是个救生员。我应该读什么来了解所有这些细微差别?@mm_u我只是随着时间的推移才学会了这一点,并不能真正指向我学习它的单一来源。@Joseph Sible,你能把double(*数据)[c.nb_cols]=(double(*)c.nb_cols])c.data解包吗代码>请?对于3-dim或4-dim阵列,您将如何执行此操作?@mm_u除第一个维度外,每个维度都应有一个单独的[]
。所以类似于double(*data)[c.nb\u cols][c.nb\u第三维度大小][c.nb\u第四维度大小]
@mm\u你应该为此发布一个新问题,包括所有代码和确切的问题细节。