How to include libraries in a mex file
59 次查看(过去 30 天)
显示 更早的评论
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 个评论
Friedrich
2012-3-22
look in the doc:
http://www.mathworks.com/help/releases/R2012a/techdoc/ref/mex.html
-I, -L and -l are the important ones here.
回答(10 个)
Ken Atwell
2012-3-23
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 个评论
James Tursa
2012-3-26
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 个评论
Carine
2012-3-26
1 个评论
James Tursa
2012-3-26
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
2012-3-26
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 个评论
Titus Edelhofer
2012-3-26
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 个评论
Carine
2012-3-28
2 个评论
Jan
2012-3-28
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
2012-3-28
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
2012-4-25
1 个评论
James Tursa
2012-4-25
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
2012-5-2
1 个评论
James Tursa
2012-5-3
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];
}
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!