How to include libraries in a mex file
57 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hi,
I am trying to make a mex file from a C one. I have a few questions. The main one is the first lines of my program are
#include "fftw3.h"
#include <fftw3.h>
however and although the fftw3 library is installed on my computer, it seems that Matlab is unable to find it as when I compile my program it says
undefined reference to `fftw_plan_many_dft'
etc. It is not the only library that include, I also have the standard stdlib.h, string.h, math.h but they don't seem to be a problem. How could I do for Matlab to understand where to find the library? The fftw3.h is in /usr/include.
Another question is: is it possible to mex non void functions, for example int or double or should I modify them? Finally a very basic question: can I put my C functions in another file and include them to the main mex (the one with mxFunction) with an #include myfunction.h? Cheers.
1 commentaire
Friedrich
le 22 Mar 2012
look in the doc:
http://www.mathworks.com/help/releases/R2012a/techdoc/ref/mex.html
-I, -L and -l are the important ones here.
Réponses (10)
Ken Atwell
le 23 Mar 2012
As Friedrich states, you will need to add a few switches to you call to MEX:
- -I to indicated the directory where your headers (.h) files are (/usr/include in your case)
- -L to indicated the directory where you library (.so) files are
- -l to indicate the name of the library file to linkage against
stdlib.h, string.h are not a problem because they are part of your compiler's distribution, and FFTW is not.
As to the return types of your function, the MEX API entry point must be void:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Use nlhs and plhs to return values.
You can put other functions in their own files, or within the C file containing mexFunction -- it is really a matter of style. If you do use separate files, you will need to add them to your MEX command line.
0 commentaires
James Tursa
le 26 Mar 2012
What happens when you try this:
#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) {
[...]
partitions[pcount] = ep;
partitions[pOff-pcount] = en;
[...]
return;
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
int N, *partitions;
int taille,k;
/* 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] = mxCreateNumericMatrix(1, taille, mxINT32_CLASS, mxREAL);
partitions = (int*) mxGetData(plhs[0]);
/* Call the subroutine. */
gft_1dPartitions(N, partitions);
return;
}
0 commentaires
Carine
le 26 Mar 2012
1 commentaire
James Tursa
le 26 Mar 2012
There should be only one mexFunction in all of your code. You can have as many different source files as you want, but there should be only one mexFunction ... it would be in exactly one of your source files. You do *not* need to change any of your C functions since they are only interfacing with other C code ... they are not interfacing with MATLAB directly. From the nature of your questions I would guess that you are going to need some help with this so I would suggest you post a small sample of code that you are trying to compile into a mex function and then we can help you set up the code and also give you help on the mex commands to use.
Titus Edelhofer
le 26 Mar 2012
Hi,
you don't need to change your code. Yes, the mex interface is with void, but there is nothing wrong doing something like the following
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
// N is the first input argument
int N = (int) mxGetPr(prhs[0])[0];
int result = ThisFunction(int N);
plhs[0] = mxCreateDoubleScalar(result);
}
Or did I miss something?
Titus
0 commentaires
Titus Edelhofer
le 26 Mar 2012
Hi,
I see. I would suggest the following:
int *pr;
[...]
// this is the result from the function:
partitions = gft_1dPartitions(N);
// this is the pointer to the result data in plhs:
pr = (int*) mxGetData(plhs[0]);
// copy partitions to pr
memcpy(pr, partions, taille*sizeof(int));
[...]
// probably you need to free the memory?
free(partitions);
Titus
0 commentaires
Carine
le 28 Mar 2012
2 commentaires
Jan
le 28 Mar 2012
If you create an mxArray of type UINT32, be sure *not* to create an (int *) pointer to its data. This will crash on 64 bit machines. Better use a (uint32_T *) pointer.
Currently the function is writing to an un-allocated partitions* array. This cannot work.
Jan
le 28 Mar 2012
James suggestion is very good and it is helpful to solve your problem. He is an experienced C-programmer. If his suggestion does not match your program design, it is worth to consider to change the design.
Carine
le 25 Avr 2012
1 commentaire
James Tursa
le 25 Avr 2012
At first glance, it looks like you are not calling mxMalloc correctly in this line:
partitions = mxMalloc(taille);
mxMalloc (like its C counterpart malloc) allocate the number of bytes requested, and I am guessing that taille is the number of *elements* you want for partitions, not the number of *bytes*. So do this instead:
partitions = mxMalloc(taille * sizeof(*partitions));
You should get in the habit of always using the form above for calling mxMalloc (or malloc) in your code. I.e., always have your coded line look like this pattern:
mypointer = malloc( (number_of_elements) * sizeof(*mypointer) );
You can get arguments both ways as to whether or not you should explicitly cast the result of malloc in the above line. In C++ you have to. In C it is optional. Leaving it out in C gives the compiler a chance to generate an error in the above line if the prototype for malloc is missing.
Carine
le 2 Mai 2012
1 commentaire
James Tursa
le 3 Mai 2012
The best way to turn win into an mxArray is to do it *before* you call gaussian. E.g.,
mxArray *mx;
double *win;
mx = mxCreateDoubleMatrix(1, N*2, mxREAL);
win = mxGetPr(mx);
gaussian( win, N, freq );
But if you can't do it that way for some reason, then you can copy the data inside gaussian(). E.g.,
void gaussian( etc ) {
:
mxArray *mx;
double *pr;
mx = mxCreateDoubleMatrix( 1, N*2, mxREAL );
pr = mxGetPr(mx);
for( i=0; i<N*2; i++ ) {
pr[i] = win[i];
}
Voir également
Catégories
En savoir plus sur Write C Functions Callable from MATLAB (MEX Files) dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!