使用Python ctypes运行C dll函数时出现问题(数组输出大小未知)

使用Python ctypes运行C dll函数时出现问题(数组输出大小未知),python,c++,c,matlab,ctypes,Python,C++,C,Matlab,Ctypes,我试图使用PythoncTypes执行一个C函数,但我做错了什么 C函数最初使用MATLAB编码器从MATLAB转换为C代码。该函数将一个长度未定义的数组作为输出,该数组取决于输入 这是MATLAB代码: function a = array_output(n) %$codegen if n > 2*pi a = 1:n; else a = [1,2,3]; end end 这是获得的C代码: void array_output(double n, emxArray_

我试图使用PythoncTypes执行一个C函数,但我做错了什么

C函数最初使用MATLAB编码器从MATLAB转换为C代码。该函数将一个长度未定义的数组作为输出,该数组取决于输入

这是MATLAB代码:

function a = array_output(n)
%$codegen

if n > 2*pi
    a = 1:n;
else
    a = [1,2,3];
end

end
这是获得的C代码:

void array_output(double n, emxArray_real_T *a)
{
  int i;
  int loop_ub;
  if (n > 6.2831853071795862) {
    i = a->size[0] * a->size[1];
    a->size[0] = 1;
    loop_ub = (int)floor(n - 1.0);
    a->size[1] = loop_ub + 1;
    emxEnsureCapacity_real_T(a, i);
    for (i = 0; i <= loop_ub; i++) {
      a->data[i] = (double)i + 1.0;
    }
  } else {
    i = a->size[0] * a->size[1];
    a->size[0] = 1;
    a->size[1] = 3;
    emxEnsureCapacity_real_T(a, i);
    a->data[0] = 1.0;
    a->data[1] = 2.0;
    a->data[2] = 3.0;
  }
}

struct emxArray_real_T
{
  double *data;
  int *size;
  int allocatedSize;
  int numDimensions;
  boolean_T canFreeData;
};
输出的
data\u struct
包含正确大小的字段(
data\u struct.size[1]
为50),但当我尝试访问
data\u struct.data[0]
时,我得到以下错误:

ValueError: NULL pointer access
有人能帮我理解我做错了什么吗

--

示例实现(代码段):

void main(){
//这里是伪代码
emxArray_real_T*a;
emxInitArray_real_T(&a,2);
/*初始化函数“数组\输出”输入参数*/
/*调用入口点“array\u output”*/
阵列输出(5.0,a);
}
无效emxInitArray\u real\T(emxArray\u real\T**pEmxArray,整数尺寸)
{
emxInit_real________________________________;
}
无效emxInit_real_T(emxArray_real_T**pEmxArray,整数尺寸)
{
emxArray_real_T*emxArray;
int i;
*pEmxArray=(emxArray_real_T*)malloc(sizeof(emxArray_real_T));
埃姆沙雷=*彭沙雷;
emxArray->data=(双*)NULL;
emxArray->numDimensions=numDimensions;
emxArray->size=(int*)malloc(sizeof(int)*numDimensions);
emxArray->allocatedSize=0;
emxArray->canFreeData=true;
对于(i=0;isize[i]=0;
}
}
无效emxEnsureCapacity_real_T(emxArray_real_T*emxArray,int oldNumel)
{
纽努梅尔国际酒店;
int i;
作废*新数据;
if(oldNumel<0){
奥尔德努梅尔=0;
}
newNumel=1;
对于(i=0;inumDimensions;i++){
newNumel*=emxArray->size[i];
}
如果(newNumel>emxArray->allocatedSize){
i=emxArray->allocatedSize;
如果(i<16){
i=16;
}
而(我1073741823){
i=最大输入32;
}否则{
i*=2;
}
}
newData=calloc((unsigned int)i,sizeof(double));
如果(emxArray->data!=NULL){
memcpy(newData,emxArray->data,sizeof(double)*oldNumel);
如果(emxArray->canFreeData){
免费(emxArray->data);
}
}
emxArray->data=(双*)新数据;
emxArray->allocatedSize=i;
emxArray->canFreeData=true;
}
}

数组输出的第二个参数是
emxArray\u real\u T*
,但是您试图通过值传递结构,就好像它只是一个
emxArray\u real\u T
。要解决此问题,请将
dll.array\u output.argtypes=[ctypes.c\u double,DataStruct]
更改为
dll.array\u output.argtypes=[ctypes.c\u double,ctypes.POINTER(DataStruct)]
dll.array\u output(50,ctypes.byref(data\u struct))
您的示例不可复制。缺少
emxEnsureCapacity\u real\u T
的定义。如果您有一个用C编写的工作
emxInitArray\u real\u T
函数,为什么您要用Python重写它,而不仅仅是调用它?@JosephSible Monica我已经编辑了我的帖子。如果您愿意,我可以分享关于您不使用
emxInitArray\u real\u T
的问题的整个输出代码,我真的只想使用主函数
array\u output
,并用Python完成剩下的部分。
ValueError: NULL pointer access
void main(){
    // pseudo-code here
    emxArray_real_T *a;
    emxInitArray_real_T(&a, 2);
    
    /* Initialize function 'array_output' input arguments. */
    /* Call the entry-point 'array_output'. */
    array_output(5.0, a);
}

void emxInitArray_real_T(emxArray_real_T **pEmxArray, int numDimensions)
{
  emxInit_real_T(pEmxArray, numDimensions);
}

void emxInit_real_T(emxArray_real_T **pEmxArray, int numDimensions)
{
  emxArray_real_T *emxArray;
  int i;
  *pEmxArray = (emxArray_real_T *)malloc(sizeof(emxArray_real_T));
  emxArray = *pEmxArray;
  emxArray->data = (double *)NULL;
  emxArray->numDimensions = numDimensions;
  emxArray->size = (int *)malloc(sizeof(int) * numDimensions);
  emxArray->allocatedSize = 0;
  emxArray->canFreeData = true;
  for (i = 0; i < numDimensions; i++) {
    emxArray->size[i] = 0;
  }
}


void emxEnsureCapacity_real_T(emxArray_real_T *emxArray, int oldNumel)
{
  int newNumel;
  int i;
  void *newData;
  if (oldNumel < 0) {
    oldNumel = 0;
  }

  newNumel = 1;
  for (i = 0; i < emxArray->numDimensions; i++) {
    newNumel *= emxArray->size[i];
  }

  if (newNumel > emxArray->allocatedSize) {
    i = emxArray->allocatedSize;
    if (i < 16) {
      i = 16;
    }

    while (i < newNumel) {
      if (i > 1073741823) {
        i = MAX_int32_T;
      } else {
        i *= 2;
      }
    }

    newData = calloc((unsigned int)i, sizeof(double));
    if (emxArray->data != NULL) {
      memcpy(newData, emxArray->data, sizeof(double) * oldNumel);
      if (emxArray->canFreeData) {
        free(emxArray->data);
      }
    }

    emxArray->data = (double *)newData;
    emxArray->allocatedSize = i;
    emxArray->canFreeData = true;
  }
}