Passing const mxArray *prhs[i] to a function gives wrong values.

Hello, I am currently writing a c++ mexFunction called by Matlab2017b. I work on a Linux machine, compiling mex with g++ gnu4.9.5.
I have more than 10 different prhs to read, and each prhs[] is copied to a struct class named Data.
In the following example, I am trying to fill the Data->XR Member. When declared in my Matlab script, XR = (0:95)*0.295e-3. However, when printing values from the MEX, I get crazy low values like 6.94882e-310.
Below is a simplified version of my code showing: the main, the function called and the class that needs to be filled.
#include <iostream>
using namespace std;
void
mexFunction (int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
Input_st *Data;
Data = new Input_st;
if (nrhs !=2) mexErrMsgIdAndTxt("Main:Input", "Number of Inputs must be 2");
int Counter = 0;
// Calling function that fills XR and NR
Data->NR = FillDataFromMxArray(Data->XR, prhs[Counter]); Counter++;
// Printing values for checking...
for (int i = 0 ; i < Data->NR ; i++)
{
cout << i << " " << Data->XR[i] << endl;
}
delete [] Data;
}
int
FillDataFromMxArray(double *pData, const mxArray *pMxArray)
{
const mwSize *pMxArrayDims;
double *pMxData;
// Check the number of elements.
pMxArrayDims = mxGetDimensions(pMxArray);
if (pMxArrayDims[0]!=1 || pMxArrayDims[1] <=0)
{
mexErrMsgIdAndTxt("FillPointerFromMxArray:Input",
"Argument with Array must be 1*N mxArray");
}
// Reading pointer to the first block of mxArray.
pMxData = (double*)mxGetData(pMxArray); //tried also with pMxData = mxGetPr(pMxArray)
pData = pMxData;
return (int)pMxArrayDims[1];
}
typedef struct Input_st {
double NR, *XR;
};
NR is correctly written but Not XR. FYI, before I was filling the Input_st directly the same way in the main/mexFunction (No FillDataFromMxArray) and values were correct.. So I am thinking it maybe because the prhs[Counter] is not passed properly.
Thanks in advance for your help, I hope everything is clear enough!
Pierre

2 Commenti

First thing, the argument you're saying is not passed properly is the 1st argument to the mex function? Your code imply that counter should be in a loop but it's not there, so you're only reading the 1st argument.
Secondly, is the passed data actually of type double?
Probably not relevant to your question but your dimension check is a bit flawed. It will accept a 1x1xN array and should return the values correctly, however the returned size (NR) will be incorrect.
Hi Guillaume,
Regarding the mex arguments, everything is fine. When I say passing argument it is only for the function FillDataFromMxArray. Before I was reading prhs[0] directly in the mexFunction/main and it worked properly.
Regarding the Counter, since I only show the reading of one prhs it is usless here I agree. It would be useful later when I'll be reading all the different arrays (>10). But the counter is not the problem here, If is put prhs[0], the problem is exactly the same (Just to be sure, prhs[0] points to the 1st argument of the mexfunction called in Matlab, prhs[1] the second, etc).
Second, I believe they are. in Matlab, whos XR gives Size = 1*96, Bytes = 768, Class = double and no Attributes. And In the function I am casting them as double*. Am I missing something?
I agree for the dimension checking, thanks for the remark!
Thanks for your help.

Accedi per commentare.

 Risposta accettata

You make a terrible mistake of pointer manipulation: passing Data->XR (a double pointer) as input argument will nener be updated after the function FillDataFromMxArray() returns.
You have two option:
  • filling inside the function or
  • pass the address of Data->XR, &(Data->XR), which would be pointer of double pointer to a function.

3 Commenti

Hi Bruno, Thanks for your answer. So I just passed as you mentioned &(Data->XR), and modified my function as follow:
int
FillPointerFromMxArray(double **pData, const mxArray *pMxArray)
{
const mwSize *pMxArrayDims;
double **pMxData;
// Check the number of elemens.
pMxArrayDims = mxGetDimensions(pMxArray);
if (pMxArrayDims[0]!=1 || pMxArrayDims[1] <=0)
{
mexErrMsgIdAndTxt("FillPointerFromMxArray:Input", "Argument with Array must be 1*N mxArray");
}
// Reading pointer to the first block of mxArray..
pMxData = (double**)mxGetData(pMxArray);
pData = pMxData;
return (int)pMxArrayDims[1];
}
I get exactly the same result.
Ok I got it! (I was just rushing it ;) )
int
FillPointerFromMxArray(double **pData, const mxArray *pMxArray)
{
const mwSize *pMxArrayDims;
double **pMxData;
// Check the number of elemens.
pMxArrayDims = mxGetDimensions(pMxArray);
if (pMxArrayDims[0]!=1 || pMxArrayDims[1] <=0)
{
mexErrMsgIdAndTxt("FillPointerFromMxArray:Input", "Argument with Array must be 1*N mxArray");
}
// Reading pointer to the first block of mxArray..
*pData = mxGetPr(pMxArray);
//pMxData = (double**)mxGetData(pMxArray);
//pData = pMxData;
return (int)pMxArrayDims[1];
}
Thanks a lot!!

Accedi per commentare.

Più risposte (0)

Categorie

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by