3

我花了一周的时间解决以下问题,但我一生都无法弄清楚!我将尽可能简短地使用代码并删除不相关的行,但我的问题应该很清楚。对于初学者,我将 Matlab 与 C 结合使用,后者通过 mex 文件进行通信。无需再费周折...

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  static double *U
  plhs[4] = mxCreateNumericArray(2,dims,mxDOUBLE_CLASS,mxREAL);
  U  = (double*)mxGetPr(plhs[4]);

  /* C code which solves for "U" based on a number of other input variables*/
  solve(U,...,...,...)

  /* C code which solves for "U" based on a number of other input variables*/
  derivative(U,...,...,...)
}

执行后,一切正常,我得到了“U”导数的价值。然后我想比较求解器,所以我将“solve(U)”换成我通过“mexCallMATLAB”调用的 Matlab 函数。这是我迷路的地方

(我再次删除了不相关的变量)

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  static double *U
  plhs[4] = mxCreateNumericArray(2,dims,mxDOUBLE_CLASS,mxREAL);
  U  = (double*)mxGetPr(plhs[4]);

  /* Call MATLAB solver */
  mxArray *Uin[8],*Uout[2];
  Uin[0] = mxCreateNumericArray(2,dims,mxSINGLE_CLASS,mxREAL);

  memcpy(mxGetPr(Uin[0]),(some variable),m*n*sizeof(float));

是的,有 8 个输入...为了简单起见,我只是删除了

  mexCallMATLAB(2,Uout,8,Uin,"my_matlab_solver");

然后,我使用以下内容检查“Uout”的结果:

  mexCallMATLAB(0,NULL,1,&Uout[0],"plot_variable");

一切都很好,但是后来调用变量“U”来查找它的导数的“C”代码不起作用。

  plhs[4] = Uout[0];

  /* C code which solves for "U" based on a number of other input variables*/
  derivative(U,...,...,...)

}

我不知道如何将“Uout[0]”分配给“U”。我认为通过设置 plhs[4] = Uout[0] 然后 U 将指向“my_matlab_solver”的结果,但事实并非如此。没有编译错误。

有没有更简单的方法可以将“my_matlab_solver”的输出直接分配给“U”,而不必为输出创建一个 mxArray?整个 MEX 的事情似乎比它需要的要复杂得多。谢谢你的帮助!

4

1 回答 1

2

如果不查看更多代码,很难判断问题出在哪里。正如我在评论中提到的,我怀疑您在错误的变量中分配了值...

这是一个玩具示例,展示如何从 MEX 函数调用 MATLAB 并操作数组。也许它会有所帮助:

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // check for proper number of input/output
    if(nrhs != 0 || nlhs > 2) {
        mexErrMsgIdAndTxt("mex:nlhs", "Wrong number of arguments.");
    } 

    // call: out1 = rand(5,5); out2 = rand(5,5);
    mxArray *Uin[2], *Uout[2];
    Uin[0] = mxCreateDoubleScalar(5);
    Uin[1] = mxCreateDoubleScalar(5);
    mexCallMATLAB(1, &Uout[0], 2, Uin, "rand");
    mexCallMATLAB(1, &Uout[1], 2, Uin, "rand");

    // compute: out = out1 + out2; and assign it to output
    plhs[0] = mxCreateDoubleMatrix(5,5,mxREAL);
    double *x = mxGetPr(Uout[0]);
    double *y = mxGetPr(Uout[1]);
    double *z = mxGetPr(plhs[0]);
    for(int i=0; i<5*5; ++i) {
        *z = *x + *y;
        ++x; ++y; ++z;
    }

    // free memory
    mxDestroyArray(Uin[0]);
    mxDestroyArray(Uin[1]);
    mxDestroyArray(Uout[0]);
    mxDestroyArray(Uout[1]);
}
于 2013-05-23T12:07:33.870 回答