Reputation: 2243
I've been at this for a couple days now, have tried every variation I can think of, and looked at countless examples. I just can't get it working.
I'm trying to make a mexFunction to call from matlab. This mexFunction calls into another C function I have, lets call it retrieveValues, and returns an array and the length of that array. I need to return both of those back to the matlab function, which as I understand it, means I need to put them in the plhs
array.
I call my mexFunction from matlab like this:
[foofooArray, foofooCount] = getFoo();
Which to my understanding, means that nlhs = 2
, plhs
is an array of length 2, nrhs = 0
, and prhs
just a pointer.
Here's my code for the mexFunction:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray* prhs[])
{
foo* fooArray
int fooCount
plhs = mxCreateNumericMatrix(1, 2, mxUINT64_CLASS, mxREAL);
//feels like I shouldn't need this
retrieveValues(&fooArray, &fooCount);
plhs[0] = fooArray;
plhs[1] = fooCount;
}
Running the matlab program gets me One or more output arguments not assigned during call
I've tested and confirmed that the values are being returned from retrieveValues
correctly.
Upvotes: 1
Views: 3231
Reputation: 124563
Here is an example:
#include "mex.h"
#include <stdlib.h>
#include <string.h>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray* prhs[])
{
// validate number of arguments
if (nrhs != 0 || nlhs > 2) {
mexErrMsgTxt("Wrong number of arguments");
}
// create C-array (or you can recieve this array from a function)
int len = 5;
double *arr = (double*) malloc(len*sizeof(double));
for(int i=0; i<len; i++) {
arr[i] = 10.0 * i;
}
// return outputs from MEX-function
plhs[0] = mxCreateDoubleMatrix(1, len, mxREAL);
memcpy(mxGetPr(plhs[0]), arr, len*sizeof(double));
if (nlhs > 1) {
plhs[1] = mxCreateDoubleScalar(len);
}
// dellocate heap space
free(arr);
}
>> mex -largeArrayDims testarr.cpp
>> [a,n] = testarr
a =
0 10 20 30 40
n =
5
Upvotes: 2
Reputation: 25140
You are correct that the plhs = mxCreateNumericMatrix(...)
is not needed. Also, note that nlhs
is the number of left-hand-sides you supply in MATLAB - so in your case, you're calling it with 2 left-hand-sides. Here's how to return trivial scalar values:
plhs[0] = mxCreateDoubleScalar(2);
plhs[1] = mxCreateDoubleScalar(3);
To handle your actual return values, you'll need to do something to copy the values out of foo
and into a newly-created mxArray. For example, if your function returned doubles, you might do this:
double * values;
int numValues;
myFcn(&values, &numValues);
/* Build a 1 x numValues real double matrix for return to MATLAB */
plhs[0] = mxCreateDoubleMatrix(1, numValues, mxREAL);
/* Copy from 'values' into the data part of plhs[0] */
memcpy(mxGetPr(plhs[0]), values, numValues * sizeof(double));
EDIT Of course someone somewhere needs to de-allocate values
in both my example and yours.
EDIT 2 Complete executable example code:
#include <string.h>
#include "mex.h"
void doStuff(double ** data, int * numData) {
*numData = 7;
*data = (double *) malloc(*numData * sizeof(data));
for (int idx = 0; idx < *numData; ++idx) {
(*data)[idx] = idx;
}
}
void mexFunction( int nlhs, mxArray * plhs[],
int nrhs, const mxArray * prhs[] ) {
double * data;
int numData;
doStuff(&data, &numData);
plhs[0] = mxCreateDoubleMatrix(1, numData, mxREAL);
memcpy(mxGetPr(plhs[0]), data, numData * sizeof(double));
free(data);
plhs[1] = mxCreateDoubleScalar(numData);
}
Upvotes: 6