Search code examples
c++matlabvisual-studio-2012mex

MATLAB MEX-file builds successfully but nothing is displayed


I am new here so I will try to expose my issue clearly: I am currently developping a program in MATLAB language that has to load a library to work properly. However, the latter is written in C/C++ (I cannot access to it) but I can call it in C++ and then create a MEX-file to use returned values. Using Visual Studio 2012, I sucessfully managed to call the library (the portRead function returns me a value when I give it parameters-values as arguments). Here is my code:

// Test704.cpp : Defines the entry point for the console application.
#define _AFXDLL
#define _tprintf mexPrintf
//#include "afx.h"
#include "StdAfx.h"
#include "704IO.h"
#include "Test704.h"
//#include "mat.h"
#include "mex.h"
//mxArray *matGetNextVariable(MATFile *mfp, const char **name);
#ifdef _DEBUG
  #define new DEBUG_NEW
#endif
/////////////////////////////////////////////////////////////////////////////

CWinApp theApp;  // The one and only application object

/////////////////////////////////////////////////////////////////////////////

using namespace std;

/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, TCHAR *argv[], TCHAR *envp[])
//void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

//int     nRetCode(0);
HMODULE hModule(::GetModuleHandle(NULL));
short   valueRead;

  if (hModule != NULL)
  {
    // Initialize MFC and print and error on failure
    if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
    {
      //_tprintf(_T("Fatal Error: MFC initialization failed\n"));
      //mexPrintf("Fatal Error: MFC initialization failed");
      //nRetCode = 1;
    }
    else
    {
      while(true)
      {
        valueRead = PortRead(1, 780, -1);
        _tprintf(_T("Value Read = %i\n"), valueRead);
        //mexPrintf("Value Read = %i",valueRead);
        Sleep(1000);  // Sleep for 1s so we can see the value on the screen
      }
    }
  }
  else
  {
    _tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
    //mexPrintf("Fatal Error: GetModuleHandle failed");
   // nRetCode = 1;
  }

  //return nRetCode;
}

/////////////////////////////////////////////////////////////////////////////
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    int _tmain();
    //short   valueRead;
    //valueRead = PortRead(1, 780, -1);
    //_tprintf(_T("Value Read = %i\n"), valueRead);
    //mexPrintf("Value Read = %i",valueRead);
    return;
}

You can see that I commented my unsuccessful researches to solve my issue... This code returns me "valueRead = 255" in a console, which means the program is working well. What I want now is to retrieve this value in MATLAB. You may also notice that I created a mexFunction; indeed, I read into documentation that a gateway to MATLAB (=the mexFunction) has to be created in C++.

Now, using MATLAB R2015a, I created the following MEX-file:

function test()    
location = 'C:\Users\admin\Documents\MATLAB\';
mylib = [location '704IO.lib'];
mex( 'Test704.cpp', mylib)

And instead of retrieving "valueRead", I just have a message that indicates

>Building with 'Microsoft Visual C++ 2012'. MEX completed successfully

So, as a summary, I have functionnal C++ code but I cannot figure out why I am unable to link it to MATLAB in order to use it! I have been seeking for the solution for days, and I think it is time for me to ask for help :)

Thanks a lot for your help! (P.-S.: I a beginner in C++, so sorry for misunderstanding/bad syntax )


Solution

  • By calling

    mex( 'Test704.cpp', mylib)
    

    you only compile the .cpp file. As a result, MATLAB tells you that MEX completed successfully, that means the compilation worked. As a result you will see a new file in the working directory: Depending on your OS, it might be called e.g. Test704.mexw64 (Windows, 64-bit), or a similar name. You need to call mex everytime you changed something in the C++ code, so the file is re-compiled.

    This compiled file/function can now be used like a normal MATLAB-function. To call it without any additional parameters, simply type

    Test704()
    

    in MATLAB. That way, the mexFunction() is executed, and that way your _tmain() will run.

    Note: your C++ code will write e.g.valueRead = 255 to the MATLAB command window, but it will not create a variable called valueRead in MATLAB. To create such a variable, you would have to return the read value from _tmain to the mexFunction, and allocate a MATLAB variable there.

    Edit: You have a bug in the mexFunction: there you write:

    int _tmain();
    

    which is not a function call, but a function declaration. You tell C++ that you have a function called _tmain(), but it is never called. What you need is a function call, i.e. only _tmain() without the int. Remember that you need to supply the parameters int argc, TCHAR *argv[], TCHAR *envp[]. I simply set these to zero here:

    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    {
        _tmain(0,0,0);
        return;
    }