Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在C结构中保存numpy数组_Python_C_Numpy_Ctypes - Fatal编程技术网

Python 在C结构中保存numpy数组

Python 在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*数据

我使用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*数据[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**数据的声明中

提前谢谢

第一个问题:
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你应该为此发布一个新问题,包括所有代码和确切的问题细节。