解引用指向MxArray的指针

时间:2014-10-28 09:36:56

标签: c matlab pointers mex

我正面临一些指针混乱:

我有一些(数字食谱)C函数fitexy(in, &out),我想编译为.mex文件,从matlab调用它。但是,我无法通过网关例程访问指针out,以便将其传递给plhs[0],我该怎么做?

我得到的最接近的(在最不容易混淆的错误信息的意义上)是:

void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[]){
float *in;
float out;

in      = (float *)mxGetData(prhs[0]);
plhs[0] = mxCreateNumericMatrix(1,1,mxSINGLE_CLASS,mxREAL);
out     = (float *)mxGetData(plhs[0]);

fitexy(in, &out);

printf("out = %lf", &out); /*Prints the correct result to the screen*/
}

这会导致编译错误消息:

error: incompatible types when assigning to type ‘float’ from type ‘float *’

这对我来说并不太令人惊讶,但也不是很有帮助。我试图转换/取消引用mxGetData(plhs[0])

的输出
out     = (float &)mxGetData(plhs[0]);

这似乎是一种废话,

out     = (float)mxGetData(plhs[0]);

out是变量和mxGetData(plhs[0])指针冲突。

我已找到Save a variable (float *) to plhsHow to return a float value from a mex function, and how to retrieve it from m-file?,但它们都涉及投射而不是解除引用。

我理解cannot convert parameter 2 from 'mxArray **' to 'mwArray &',但它对我没有帮助,因为我不能(即不愿意)改变对我的C程序的调用。

非常感谢任何帮助,非常感谢!

2 个答案:

答案 0 :(得分:3)

为什么不将out定义为指针?

float * out;

通过这种方式,您可以轻松完成

out     = (float *)mxGetData(plhs[0]);

您可以使用out来编写结果值。如果我没有弄错fitexy()函数,可以用

调用它
fitexy(in, out);

答案 1 :(得分:2)

假设您有一个带有以下签名的C函数fit_line

void fit_line(float x[], float y[], int n, float *a, float *b);

它需要两个长度为x的输入数据数组yn,并通过计算量子least-squares sense拟合直线y = a*x + b { {1}}和a

以下是我编写MEX函数的方法:

mex_fit_line.c

b

编译之后,我们可以从MATLAB调用MEX函数:

#include "mex.h"

EXTERN_C void fit_line(float x[], float y[], int n, float *a, float *b);

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    /* validate inputs */
    if (nrhs!=2 || nlhs>2)
        mexErrMsgIdAndTxt("mex:err", "wrong num args");
    if (!mxIsSingle(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) ||
        !mxIsSingle(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]))
        mexErrMsgIdAndTxt("mex:err", "expecting dense real single arrays");
    if (mxGetNumberOfElements(prhs[0]) != mxGetNumberOfElements(prhs[1]))
        mexErrMsgIdAndTxt("mex:err", "length dont match");

    /* get data arrays */
    mwSize len = mxGetNumberOfElements(prhs[0]);
    float *x = (float*) mxGetData(prhs[0]);
    float *y = (float*) mxGetData(prhs[1]);
    if (x==NULL || y==NULL) mexErrMsgIdAndTxt("mex:err", "null ptr");

    /* call external function */
    float a, b;
    fit_line(x, y, len, &a, &b);

    /* assign output */
    plhs[0] = mxCreateNumericMatrix(1, 1, mxSINGLE_CLASS, mxREAL);
    *((float*) mxGetData(plhs[0])) = a;
    if (nlhs>1) {
        plhs[1] = mxCreateNumericMatrix(1, 1, mxSINGLE_CLASS, mxREAL);
        *((float*) mxGetData(plhs[1])) = b;
    }
}

plot