What could alter the behavior of a c++ library in a mex function ?

Hello,
I am trying to interface a camera to matlab in a context of development of a microscope. The idea is to control it (change parameters like exposure time/frame rate/etc and of course acquire images) directly from the Matlab environnement.
The camera comes with a developement kit in c++ that works perfectly. I would like to wrap those c++ functions in a mex function that I could call from matlab in order to control the camera directly from Matlab where I intend to manipulate the images/instrument more or less in real time.
So I first wrote some code in c++ using the dedicated camera provider library and exempled functions, compiled it, and tested it. And it works great! For exemple the following code asks the camera on how many bites are coded each pixel of the images the camera stream. The answer is suppose to be 8 or 12 bites/pixel) and indeed when compiling/calling this function I can read "PixelFormat: Mono8,Mono12,Mono12Packed" in the terminal.
#include <EmergentCameraAPIs.h>
#include <iostream>
#define SUCCESS 0
#define MAX_CAMERAS 1
void Camera_connection_routine(Emergent::CEmergentCamera* camera);
int main(int argc, char *argv[])
{
// Camera connection
Emergent::CEmergentCamera camera;
Camera_connection_routine(&camera);
// Using a function from the library to do something with the camera
const unsigned long enumBufferSize = 1000;
char enumBuffer[enumBufferSize];
unsigned long enumBufferSizeReturn = 0;
Emergent::EVT_CameraGetEnumParamRange(&camera, "PixelFormat", enumBuffer, enumBufferSize, &enumBufferSizeReturn);
std::cout << "PixelFormat: " << enumBuffer << "\n";
};
But if I put this code in mex format and compile it in Matlab I get another answer : not "PixelFormat: Mono8,Mono12,Mono12Packed"" as I should but "PixelFormat: Mono8,Mono10,Mono10Packed," !
More generally the majority of functions from the library work as they should in the matlab environnement but some do not work as expected sending different results then the one I get with the cpp function compiled with g++ in the terminal.
What could be the cause of this discrepancy ? What can I be doing that alters the way the library works/is called ?
How I compile the mex function (no error or warnign message during compilation) :
header_path = ['-I' '/private/interface_camera/include'];
lib_path = ['-L' '/stillprivate/interface_camera/lib'];
mex(header_path,lib_path,'-lEmergentCamera','mex_exemple4matlab_community.cpp')
How I wrap in a mex :
#include "mex.hpp"
#include "mexAdapter.hpp"
#include <EmergentCameraAPIs.h>
#define SUCCESS 0
#define MAX_CAMERAS 1
void Camera_connection_routine(Emergent::CEmergentCamera* camera);
class MexFunction : public matlab::mex::Function {
public:
void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
// Camera connection
Emergent::CEmergentCamera camera;
Camera_connection_routine(&camera);
// Using a function from the library to do something with the camera
const unsigned long enumBufferSize = 1000;
char enumBuffer[enumBufferSize];
unsigned long enumBufferSizeReturn = 0;
Emergent::EVT_CameraGetEnumParamRange(&camera, "PixelFormat", enumBuffer, enumBufferSize, &enumBufferSizeReturn);
std::cout << "PixelFormat: " << enumBuffer << "\n";
}
};
Thank you very much !

9 Comments

In the C++ code you reserve 1000 characters:
char enumBuffer[1000];
But only 1 in the MEx version:
char enumBuffer;
How did this even compile in C++ as a mex routine? In the working case OP is passing a pointer to char in that last spot, and in the mex case OP is passing a char in that last spot. Didn't the compiler complain? What does the prototype for EVT_CameraGetEnumParamRange( ) look like? Are there multiple methods available for different argument types in the last spot?
Thanks @JanJan & @James Tursa for taking the time to have a look at my issue.
So indeed what you saw do not compile : it was intended at pseudo code to show the general idea. But I can see that you need more in order to help me so I edited my original questions. The 2 codes that you now see are codes that are sucessfully compiled by g++ and Matlab.
@James Tursa EVT_CameraGetEnumParamRange prototype :
EMERGENTCAMERAAPI EVT_ERROR EVT_CameraGetEnumParamRange(CEmergentCamera* camera, const char* name, char* buffer, unsigned long bufferSize, unsigned long* valueSize);
And I am not sure on how to check if multiple methods are available ( it is the first time I do c++ ). In the .h where the function is defined I can only find this definition.
I believe std::cout redirection is not working in mex/matlab.
To print something on screen you need too call mexPrintf
It works well for me.
std::cout << "Hi \n"; gives me a "Hi" in the matlab console.
Which other routines are misbehaving and how are they misbehaving? Maybe that will shed some light on what is going on. Couple of things to try:
Can you compile as a regular mex routine and see what happens? E.g.,
#include "mex.h"
// your other headers, macros, etc. go here
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{ your executable code goes here }
Can you compile this as a C routine instead of a C++ routine and see what happens?
Hi,
@James Tursa I have only two others functions that do not work :
  1. A function used to ask the camera the accepted increment when setting the sensor width and height. For exemple my camera sensor is 800x616 pixel but I can tune the active area of the sensor and the accepted area is defind as a multiple of increments. My camera is suppose to accept a number of lines N_x*16 and number of row N_y*8 with N_x and N_y integer (so the increments are 16 and 8). If I use the function in a terminal context I get the right answer (16 & 8) but if I call it in the mex/matlab environnement I get a 128 and 4... The function prototype is :
EMERGENTCAMERAAPI EVT_ERROR EVT_CameraGetUInt32ParamInc(CEmergentCamera* camera, const char* name, unsigned int* inc);
exemple :
unsigned int height_max;
ReturnVal = EVT_CameraGetUInt32ParamInc(&camera, "Height", &height_max);
1'. This fonction can also used to get the offset increment depending on the camera. So again if I use only a region of 320*160 pixels I can chose to use the ones at the center of the camera using an offset that is defined again as a multiple of an increment. The increment are 16 and 4 for the x and y directions, I get 16 and 4 using the function in the terminal, but I get 128x4 in mex/matlab.
2.A function to get the camera's temperature. When calling it in matlab/mex I get a general error code, whereas I get celsius in a terminal. Prototype :
EMERGENTCAMERAAPI EVT_ERROR EVT_CameraGetInt32Param(CEmergentCamera* camera, const char* name, int* val);
Exemple :
int Temp;
ReturnVal = EVT_CameraGetInt32Param(&camera, "SensTemp" , &Temp);
I will try the C idea and let you know, but I am not sure the c++ library is c compatible.
About the idea to compile in C, it does not work as the library declares at some point this :
#include <list>
And I can't find a equivalent in C.
I am upping this question.
Even Chatgpt could not help me. Who wants to beat the ai ?

Sign in to comment.

 Accepted Answer

This question was almost two years ago, but I came back to it and find out that evaluating my mex function in another process using the function mexhost() and feval() solved the issue.
host_process = mexhost;
[out]=feval(host_process,'my_mex_fun',param);
However I have no clue why this solved the issue.
On this page https://fr.mathworks.com/help/matlab/matlab_external/out-of-process-execution-of-c-mex-functions.html I can see that out of process execution enable "Use some third-party libraries in the C++ MEX function that are not compatible with MATLAB." But it not clear to me why some third party lib could or not compatible with matlab. If somebody knows, I am interested.

More Answers (0)

Categories

Products

Release

R2022a

Asked:

on 14 Sep 2022

Answered:

on 24 May 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!