Array of int at the output of a mex file

7 visualizaciones (últimos 30 días)
Carine
Carine el 15 de Mzo. de 2012
I am trying to create a mex function whose entry is an integer and whose output is an array of integers. So the function looks like: int *myFunction(unsigned int N). In the mexFunction, I declare a variable *vari of type int and then
N = mxGetScalar(prhs[0]);
/* assign a pointer to the output */
siz= 2*round(log2(N))+1;
plhs[0] = mxCreateDoubleMatrix(1,siz, mxREAL);
vari = (int*) mxGetPr(plhs[0]); */
/* Call the subroutine. */
vari = myFunction(N);
mexPrintf("The first value is %d\n", vari[0]);
The thing is the first value is the correct one (and the other ones were checked and were correct as well) but when I call the routine mxFunction(16), I get only 0's as output. I guess it is because my output is an array of int but I don't know how to solve the problem. Any hint? Cheers.

Respuesta aceptada

Friedrich
Friedrich el 15 de Mzo. de 2012
The following code runs fine (not sure what the expected output is but it seems good):
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/utsname.h>
#endif
#include "mex.h"
void gft_1dPartitions(unsigned int N, int* partitions){
int sf = 1;
int cf = 1;
int width = 1;
int pcount = 0;
int pOff;
int ep,en;
pOff = round(log2(N))*2-1;
while (sf < N/2) {
ep = cf+width/2-1;
en = N-cf+width/2+1;
if (ep > N) ep = N;
if (width/2 == 0)
ep+=1;
partitions[pcount] = ep;
partitions[pOff-pcount] = en;
pcount++;
sf = sf+width;
if (sf > 2) width *= 2;
cf = sf+width/2;
}
partitions[pOff+1] = -1;
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
int N, *partitions;
int taille,k;
double *partdouble;
N = mxGetScalar(prhs[0]);
taille = 2*round(log2(N))+1;
plhs[0] = mxCreateNumericMatrix(1, taille, mxINT32_CLASS, mxREAL);
partitions = (int*) mxGetData(plhs[0]);
gft_1dPartitions(N,partitions);
mexPrintf("The first value is %d\n",partitions[0]);
mexPrintf("The second value is %d\n",partitions[1]);
return;
}

Más respuestas (2)

Jan
Jan el 15 de Mzo. de 2012
You define "partitions" twice:
  1. partitions = (int*) mxGetPr(plhs[0]); This is dangerous, because myGetPr replies a pointer to a double array. Better use mxGetData as in the commented section.
  2. partitions = gft_1dPartitions(N); This overwrites the former definition.It is recommended to use mxMalloc instead of malloc inside MEX functions. If you really want to use malloc, do not forget to let "free" release the reserved memory afterwards.
I think, you want to forward the pointer to the reserved memory block to the subfunction:
taille = 2*round(log2(N))+1;
plhs[0] = mxCreateNumericMatrix(1, taille, mxINT32_CLASS, mxREAL);
partitions = (int*) mxGetData(plhs[0]);
gft_1dPartitions(N, partitions);
Then you write directly to the memory in the lefthand side of the Mex function and the malloc inside the subfunction is removed.

Carine
Carine el 15 de Mzo. de 2012
Hi Friedrich,
Thanks for your answer. Here is a more complete sample of my code
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/utsname.h>
#endif
#include "mex.h"
int *gft_1dPartitions(unsigned int N) {
int sf = 1;
int cf = 1;
int width = 1;
int pcount = 0;
int pOff;
int *partitions;
int ep,en;
partitions = (int *)malloc(sizeof(int)*round(log2(N))*2+1);
pOff = round(log2(N))*2-1;
while (sf < N/2) {
ep = cf+width/2-1;
en = N-cf+width/2+1;
if (ep > N) ep = N;
if (width/2 == 0)
ep+=1;
partitions[pcount] = ep;
partitions[pOff-pcount] = en;
pcount++;
sf = sf+width;
if (sf > 2) width *= 2;
cf = sf+width/2;
}
partitions[pOff+1] = -1;
return partitions;
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
int N, *partitions;
int taille,k;
double *partdouble;
/* get the scalar value of the input x */
/* note: mxGetScalar returns a value, not a pointer */
N = mxGetScalar(prhs[0]);
/* assign a pointer to the output */
taille = 2*round(log2(N))+1;
plhs[0] = mxCreateDoubleMatrix(1,taille, mxREAL);
partitions = (int*) mxGetPr(plhs[0]);
/* plhs[0] = mxCreateNumericMatrix(1, taille, mxINT32_CLASS, mxREAL);
partitions = (int*) mxGetData(plhs[0]);*/
/* Call the subroutine. */
/*gft_1dPartitions(partitions,N);*/
partitions = gft_1dPartitions(N);
mexPrintf("The first value is %d\n",partitions[0]);
mexPrintf("The second value is %d\n",partitions[1]);
return;
}
Following your suggestion, I have tried with mxCreateNumericMatrix but it didn't change anything. The output is still an array of 0 while partitions does have the expected values. I don't quite understand why you say I overwrite vari and how I should avoid it. Sorry but I am a newbie in mex. Cheers
  3 comentarios
Friedrich
Friedrich el 15 de Mzo. de 2012
And IMPORTANT:
delte this line
partitions = (int *)malloc(sizeof(int)*round(log2(N))*2+1);
You already allocated the memory for partitions!
Carine
Carine el 15 de Mzo. de 2012
Thanks, it works! Does this mean that all C functions should be void when want to mex them?

Iniciar sesión para comentar.

Categorías

Más información sobre Write C Functions Callable from MATLAB (MEX Files) en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by