如何将float[][]类型的数组转换为"emxArray_real_T *x"

3

我已经使用MatlabCoder将一个以NxN矩阵作为输入并输出NxN矩阵的函数从Matlab转换成了C语言。 它给了我一个有两个参数的函数,分别是

void func(const emxArray_real_T *x, emxArray_real_T *y)

我知道x是函数的输入,而且我可以从y得到函数的输出。

问题在于我有一个浮点数数组float[][],我希望将这些数据作为输入提供给一个只接受emxArray_real_T *x作为输入的函数。

你有什么想法如何将这个float[][]数据转换为emxArray_real_T *x?

emxArray_real_T的结构如下:

struct emxArray_real_T
{
    real_T *data;
    int32_T *size;
    int32_T allocatedSize;
    int32_T numDimensions;
    boolean_T canFreeData;
};
2个回答

5
基本上您需要使emxArray*data成员指向float数组。在C中,float数据以single精度存储。相应地更新emxArray的其他成员。
您可能想查看MathWorks有关用于数组的C代码接口的文档
答案包含完全相同的场景,适用于double数据类型的C#实现。

3
我发现后来我们可以使用以下步骤将任何数据创建为emxArray_real_T*...
步骤1:假设您有一个包含浮点数或双精度数或其他任何类型的数组...它有2个维度..它可以是任意维度..它可以是3个..它可以是4个... 现在第一步是声明。
emxArray_real_T *x, *y;

输入 x,会得到输出 y...

目前为止,我们只声明了变量,没有设置任何维度或大小...

第二步:在你想调用的函数所在的同一个文件中,应该有这些函数...如果没有,那么你必须声明它们...

 static void emxInit_real_T(emxArray_real_T **pEmxArray, int32_T numDimensions)
 {
   emxArray_real_T *emxArray;
   int32_T i;
   *pEmxArray = (emxArray_real_T *)malloc(sizeof(emxArray_real_T));
   emxArray = *pEmxArray;
   emxArray->data = (real_T *)NULL;
   emxArray->numDimensions = numDimensions;
   emxArray->size = (int32_T *)malloc((uint32_T)(sizeof(int32_T) * numDimensions));
   emxArray->allocatedSize = 0;
   emxArray->canFreeData = TRUE;
   for (i = 0; i < numDimensions; i++) {
     emxArray->size[i] = 0;
   }
 }

现在您可以按照以下方式初始化变量“x,y”:
emxInit_real_T(&x, 2);
emxInit_real_T(&y, 2);

这里的2是我们想要作为输入或输出的矩阵的维度。

步骤3:在我的情况下,x的维度为2,所以我会这样做。假设我的输入是n * n矩阵,那么我会这样做:

x->size[0]=n;
x->size[1]=n;

同样的,对于y也是如此

y->size[0]=n;
y->size[1]=n;

如果您有3或4个维度,那么您可以添加更多,例如x->size[2]=该尺寸..以此类推。

步骤4:现在我们已经确保程序将指定的内存分配给这些变量,因此必须有一个以下函数..如果没有,您必须声明它...

static void emxEnsureCapacity(emxArray__common *emxArray, int32_T oldNumel,
  int32_T elementSize)
{
  int32_T newNumel;
  int32_T i;
  void *newData;
  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) {
      i <<= 1;
    }

    newData = calloc((uint32_T)i, (uint32_T)elementSize);
    if (emxArray->data != NULL) {
      memcpy(newData, emxArray->data, (uint32_T)(elementSize * oldNumel));
      if (emxArray->canFreeData) {
        free(emxArray->data);
      }
    }

    emxArray->data = newData;
    emxArray->allocatedSize = i;
    emxArray->canFreeData = TRUE;
  }
}

为了实现这一点,应该像下面这样有一个名为emxArray__common的结构体名称,如果没有,则应该像下面这样声明它。

struct emxArray__common
{
  void *data;
  int32_T *size;
  int32_T allocatedSize;
  int32_T numDimensions;
  boolean_T canFreeData;
};
typedef struct emxArray__common emxArray__common;

第五步:然后按照以下步骤进行...
emxEnsureCapacity((emxArray__common *)x, 0, (int32_T)sizeof(real_T));
emxEnsureCapacity((emxArray__common *)y, 0, (int32_T)sizeof(real_T));

现在这两个变量都有指定的n*n内存。 现在输入数据将保存在x的数据中...它将以行方式保存。

x->data[i*n+j]=input_data[i][j];

如果你理解了“it”的含义,现在你可以将x和y传递到要调用的函数中,返回的数据将在y中以行的方式呈现。因此,请仔细阅读并执行matlab函数在c中的操作。


这个答案是可行的,但它使用了 MATLAB Coder 生成的函数,这些函数不应该被外部使用。@TheCodeArtist发布的文档我的另一个答案表明,<functionName>_emxAPI.h中的函数,如emxCreate...应该被使用。在codegen/<lib|dll|exe>/foo/examples/main.c中的示例main函数为您特定生成的代码提供了一个具体的示例。 - Ryan Livingston

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接