Matlab C Shared Library (Call Your Own Matlab Functions)
| Table of Contents |
Abstract
mcc enables you to call your own matlab functions from C.
Compile .m and create .dll so that C can call matlab functions
Instruction
Generate C routines from .m files using mcc
Create a directory where you will store generated library files by mcc. Let yourtoolpath be the path.
I create a library libpca from my own matlab function files, cvPca.m (Principal Component Analysis), cvPcaProj.m (Project onto PCA subspace), and cvPcaInvProj.m (Back project from PCA subspace) as an example.
mcc -W lib:libpca -T link:lib cvPca.m cvPcaProj.m cvPcaInvProj.m -d yourtoolpath
This generates libpca.lib, libpca.h, and so on in the yourtoolpath and it enables to call these functions by mlfXxx in C such as mlfCvPca, mlfCvPcaProj, mlfCvPcaInvProj for cvPca.m, cvPcaProj.m, cvPcaInvProj.m respectively.
Set up your compiler -- MS Visual Studio's case
Open MS Visual Studio
- Tools > Options > Projects and Solutions > VC++ directories >
- Show Directory for: > Include Files. Now add
yourtoolpath
- Show Directory for: > Library Files. Now add
yourtoolpath
Set Windows System Environment
- Control Panel > System > Advanced > Environment Variables
- Find 'Path' and Edit. Now add
;yourtoolpath
- Reboot
Tips: To set system environment without rebooting, install SUPTOOLS.MSI from Windows XP Installer CD, then use
setx PATH %PATH%;yourtoolpath\lib
on cmd.exe.
Example
Build and run.
// required libraries to link
#ifdef _MSC_VER // if MS Visual C++
#pragma warning(push)
#pragma warning(disable:4996)
#pragma comment(lib, "libdfblas.lib")
#pragma comment(lib, "libdflapack.lib")
#pragma comment(lib, "libemlrt.lib")
#pragma comment(lib, "libeng.lib")
#pragma comment(lib, "libfixedpoint.lib")
#pragma comment(lib, "libmat.lib")
#pragma comment(lib, "libmex.lib")
#pragma comment(lib, "libmwblas.lib")
#pragma comment(lib, "libmwlapack.lib")
#pragma comment(lib, "libmwmathutil.lib")
#pragma comment(lib, "libmwservices.lib")
#pragma comment(lib, "libmx.lib")
#pragma comment(lib, "libut.lib")
#pragma comment(lib, "mclcom.lib")
#pragma comment(lib, "mclcommain.lib")
#pragma comment(lib, "mclmcr.lib")
#pragma comment(lib, "mclmcrrt.lib")
#pragma comment(lib, "mclxlmain.lib")
#pragma comment(lib, "libpca.lib")
#endif
#include "libpca.h"
#include <stdio.h>
#include "mex.h"
void display(const mxArray* in);
int run_main(int argc, char **argv);
int run_main(int argc, char **argv)
{
double data[] = {1,2,3,4,5,6,7,8,9};
mxArray *Dat, *M; // input
mxArray *V = NULL, *Me = NULL, *Lambda = NULL; // output
//Output arguments must be initialized by NULL
/* Call the mclInitializeApplication routine.
* Make sure that the application
* was initialized properly by checking the return status.
* This initialization has to be done before calling any
* MATLAB API's or MATLAB Compiler generated
* shared library functions. */
if( !mclInitializeApplication(NULL,0) )
{
fprintf(stderr, "Could not initialize the application.\n");
return -1;
}
/* Create the input data */
Dat = mxCreateDoubleMatrix(3,3,mxREAL);
memcpy(mxGetPr(Dat), data, 9*sizeof(double));
M = mxCreateDoubleScalar(1);
/* Call the library intialization routine and make sure that the
* library was initialized properly. */
if (!libpcaInitialize()){
fprintf(stderr,"Could not initialize the library.\n");
return -2;
}
else
{
mlfCvPca(2, &V, &Me, &Lambda, Dat, M);
display(V);
/* Call the library termination routine */
libpcaTerminate();
/* Free the memory created */
mxDestroyArray(V);
mxDestroyArray(Me);
mxDestroyArray(Lambda);
mxDestroyArray(Dat);
mxDestroyArray(M);
}
/* Note that you should call mclTerminate application
* at the end of your application.
*/
mclTerminateApplication();
return 0;
}
/**
* This is nothing but a utility function.
*
* display the double matrix stored in an mxArray.
* This function assumes that the mxArray passed as input
* contains double array.
*/
void display(const mxArray* in)
{
int i=0, j=0; /* loop index variables */
int r=0, c=0; /* variables to store the row and
* column length of the matrix */
double *data; /* variable to point to the double
* data stored within the mxArray */
/* Get the size of the matrix */
r = mxGetM(in);
c = mxGetN(in);
/* Get a pointer to the double data in mxArray */
data = mxGetPr(in);
/* Loop through the data and display the same in matrix format */
for( i = 0; i < c; i++ ){
for( j = 0; j < r; j++){
printf("%4.2f\t",data[j*c+i]);
}
printf("\n");
}
printf("\n");
}
/**
* Call "run_main" function using mclRunMain
* for Mac OSX compatibility.
*/
int main()
{
mclmcrInitialize();
return mclRunMain((mclMainFcnType)run_main,0,NULL);
}
Example 2
Assemble initialization steps into one function, so do termination steps.
// required libraries to link
#ifdef _MSC_VER // if MS Visual C++
#pragma warning(push)
#pragma warning(disable:4996)
#pragma comment(lib, "libdfblas.lib")
#pragma comment(lib, "libdflapack.lib")
#pragma comment(lib, "libemlrt.lib")
#pragma comment(lib, "libeng.lib")
#pragma comment(lib, "libfixedpoint.lib")
#pragma comment(lib, "libmat.lib")
#pragma comment(lib, "libmex.lib")
#pragma comment(lib, "libmwblas.lib")
#pragma comment(lib, "libmwlapack.lib")
#pragma comment(lib, "libmwmathutil.lib")
#pragma comment(lib, "libmwservices.lib")
#pragma comment(lib, "libmx.lib")
#pragma comment(lib, "libut.lib")
#pragma comment(lib, "mclcom.lib")
#pragma comment(lib, "mclcommain.lib")
#pragma comment(lib, "mclmcr.lib")
#pragma comment(lib, "mclmcrrt.lib")
#pragma comment(lib, "mclxlmain.lib")
#pragma comment(lib, "libpca.lib")
#endif
#include "libpca.h"
#include <stdio.h>
#include "mex.h"
void display(const mxArray* in);
int mxInitialization();
int mxTermination();
int mxInitialization()
{
mclmcrInitialize();
/* Call the mclInitializeApplication routine.
* Make sure that the application
* was initialized properly by checking the return status.
* This initialization has to be done before calling any
* MATLAB API's or MATLAB Compiler generated
* shared library functions. */
if( !mclInitializeApplication(NULL,0) )
{
fprintf(stderr, "Could not initialize the application.\n");
return -1;
}
/* Call the library intialization routine and make sure that the
* library was initialized properly. */
if (!libpcaInitialize()){
fprintf(stderr,"Could not initialize the library.\n");
return -2;
}
return 0;
}
int mxTermination()
{
/* Call the library termination routine */
libpcaTerminate();
/* Note that you should call mclTerminate application at the end of
* your application.
*/
mclTerminateApplication();
return 0;
}
int main(int argc, char **argv)
{
int err;
if ( (err = mxInitialization()) != 0) {
return err;
}
mxArray *Dat, *M; // input
mxArray *V = NULL, *Me = NULL, *Lambda = NULL; // output
// Output arguments must be initialized with NULL.
double data[] = {1,2,3,4,5,6,7,8,9};
/* Create the input data */
Dat = mxCreateDoubleMatrix(3,3,mxREAL);
memcpy(mxGetPr(Dat), data, 9*sizeof(double));
M = mxCreateDoubleScalar(1);
mlfCvPca(2, &V, &Me, &Lambda, Dat, M);
display(V);
/* Free the memory created */
mxDestroyArray(V);
mxDestroyArray(Me);
mxDestroyArray(Lambda);
mxDestroyArray(Dat);
mxDestroyArray(M);
if ( (err = mxTermination()) != 0) {
return err;
}
return 0;
}
/**
* This is nothing but a utility function.
*
* display the double matrix stored in an mxArray.
* This function assumes that the mxArray passed as input
* contains double array.
*/
void display(const mxArray* in)
{
int i=0, j=0; /* loop index variables */
int r=0, c=0; /* variables to store the row and
* column length of the matrix */
double *data; /* variable to point to the double
* data stored within the mxArray */
/* Get the size of the matrix */
r = mxGetM(in);
c = mxGetN(in);
/* Get a pointer to the double data in mxArray */
data = mxGetPr(in);
/* Loop through the data and display the same in matrix format */
for( i = 0; i < c; i++ ){
for( j = 0; j < r; j++){
printf("%4.2f\t",data[j*c+i]);
}
printf("\n");
}
printf("\n");
}
Mcc and Compilers Compatibility Table
| Matlab | MS VC++ | gcc | Borland |
| 2008b (7.7) | up to 2008 | ||
| 2008a (7.6) | |||
| 2007b (7.5) | up to 2005? | ||
| 2007a (7.4) | |||
| 2006b (7.3) | |||
| 2006a (7.2) | |||
| R14SP3 (7.1) | up to 7.1 |
Reference
- Compile .m and create .dll so that C can call matlab functions

- There is no matlab.h anymore, use mexCallMATLAB
