Matlab is a great tool for simulating and analyzing data. Its quite easy to write a script, that will do whatever you want since matlab has build-in functions for almost anything. However everything comes with cons as well. If you are doing some extra hard work with matlab, you may notice its quite slow, especially when it comes to for-cycles. Furthermore, If you are developing an algorithm, or testing the functionality of your C++ code, matlab is a great companion, because you can easily visualize your data with one or two commands.

Fortunately there is a way you can call your externall c++ code directly from matlab! You just have to create “a mex file”. To be more specific, you need to build a file “**someting.mexw32**” or “**something.mexw64**“. Of course,if you are building a mex file, make sure to choose correct version. You cant run .mex64 from 32-bit matlab and .mexw32 from 64-bit matlab. We will start from beginning:

- Open your Visual Studio 2013 and create a new Visual C++ Win32 project.
- Select Console Application and check “empty project”
- Under Source Files, add new Source.cpp

##### Now comes the funny part. Open your Project Settings.

- Click General – Target Extension and change it to: ” .mexw32 “
- Change Configuration Type to: ” Dynamic Library (.dll) “
- C/C++ -> General -> Additional Include Directories: ” … Matlab2014A32Bit\extern\include”
- Linker -> General -> Additional Library Directories: ” … Matlab2014A32Bit\extern\lib\win32\microsoft”
- Linker -> Input -> Additional Dependecies: Add “libmat.lib“, “libmex.lib” and “libmx.lib“
- Linker -> Command Line -> Additional Options: “/export:mexFunction“

Now we can finally proceed to some code. Each mexfile has a function “**MexFunction**” visible only to matlab, however you can have as many other functions as you want in the source file. feel free to include any files you want. You can of course use other libraries as well. I will demonstrate the usage of a mexfile on a simple example,t hat will consist of adding 13 to a matlab input Matrix. But before I post anything, please note, that matlab uses column-major order for storing multidimensional arrays. Furthermore, Matlab primarly uses double precision (Thats why is it so slow :D ).

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
#include <iostream> #include <fstream> #include <math.h> #include <matrix.h> #include <mex.h> using namespace std; //COLUMN MAJOR -> ROW MAJOR| Double to single void colToRow(double *input, float *output, int Nx, int Ny){ int counter = 0; for (int i = 0; i < Ny; i++){ for (int j = 0; j < Nx; j++){ int index = j*Ny + i; output[counter] = input[index]; counter++; } } } //ROW MAJOR -> COLUMN MAJOR | Single to Double void rowToCol(double *output, float* input, int Nx, int Ny){ int counter = 0; for (int i = 0; i < Ny; i++){ for (int j = 0; j < Nx; j++){ int index = j*Ny + i; output[index] = input[counter]; counter++; } } } //THIS IS A MUST-HAVE FUNCTION void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //prhs = Pointer to The Right Hand Side --- INPUT //plhs = Pointer to The Left Hand Side --- OUTPUT mxArray *matlabInput, *matlabOutput; const mwSize *dimsInput; double *input_double, *output_double; //Standard C - Pointers float *singleData; //Standard C - Pointer int Nx, Ny, numDimInput; //Matrix Dimensions //ASSOCIATE INPUT matlabInput = mxDuplicateArray(prhs[0]); //FIGURE OUT DIMENSIONS dimsInput = mxGetDimensions(prhs[0]); numDimInput = mxGetNumberOfDimensions(prhs[0]); Ny = (int)dimsInput[0]; Nx = (int)dimsInput[1]; //ALLOCATE MEMORY FOR SINGLE PRECISION singleData = (float*)malloc(Nx*Ny*sizeof(float)); //CONVERT INPUT TO STANDARD 1D C-Pointers input_double = mxGetPr(matlabInput); //TRANSFORM TO ROW-MAJOR ORDER colToRow(input_double, singleData, Nx, Ny); // --- --- DO WHATEVER YOU WANT HERE --- --- for (int i = 0; i < Ny; i++){ for (int j = 0; j < Nx; j++){ int index = i*Nx + j; singleData[index] = singleData[index] + 13; } } // -- --- YOUR CODE END HERE --- --- //ASSOCIATE OUTPUT AS A 2D Matrix matlabOutput = plhs[0] = mxCreateDoubleMatrix(Ny, Nx, mxREAL); //CONVERT OUTPUT TO STANDARD 1D C-Pointers output_double = mxGetPr(matlabOutput); //TRANFORM BACK TO COLUMN-MAJOR ORDER rowToCol(output_double, singleData, Nx, Ny); //FREE USED MEMORY std::free(singleData); return; } |

As you can see, Its quite easy to create a MEX File. I believe the code should be self-explananotry with the comments provided. To sum it up, we obtain an mxArray variable from matlab, create a local instance of the array, then we derive its dimensions (Nx,Ny – Note Ny is at position = 0), get the standard 1D C++ Double pointer and as I mentioned before, we do a Column-to-Row operation. Then we are free to do whatever we want (Add 13 :D). After we are finished, we define output as mxArray, get its 1D C++ Double Pointer and do a Row-to-Column Operation. All you have to do now is to call this function from matlab (MatlabSimpleMex was the name of my project):

1 2 3 4 5 6 7 8 9 10 11 |
clear all;close all;clc; Nx = 7; % X - Dimension Ny = 11; % Y - Dimension INPUT = rand(Ny,Nx); % Generate some input data OUTPUT = MatlabSimpleMex(INPUT); % Add 13 to this data using our C++ mexLib % Do This :) clear mex; |

- The “clear mex” command enables you to rebuild your mex file from Visual Studio without closing matlab.
- Use ” mexPrintf() ” function – similar to printf() – to write to matlab command window.
- If you are willing to create higher dimensional output than 2D, use the “mxCreateNumericArray()“
- Use mxGetPr() and mxGetPi() for Real and Imaginary Data Pointers.
- If you wonder,why I am adding 13, check google for “Taylor Swift’s favorite number ” :)