Can I use the Matlab engine in a non-mex library?

2 vues (au cours des 30 derniers jours)
Jeroen Boschma
Jeroen Boschma le 23 Juin 2023
Commenté : Jeroen Boschma le 24 Juin 2023
The working situation is as follows:
  1. a library 'CPP_LIB' with ordinary C++ functions is compiled and built
  2. a mex-file is generated, it calls functions from 'CPP_LIB' so the mex is linked to 'CPP_LIB'
This works, but: now I want to be able to use the Matlab engine and call Matlab functions from within 'CPP_LIB'. That does not work, I get all sorts of compiler errors as soon as I even include <mex.hpp> and <mexAdapter.hpp>. Is there any way to do this?
  2 commentaires
James Tursa
James Tursa le 23 Juin 2023
Modifié(e) : James Tursa le 23 Juin 2023
It is not clear exactly what you are doing. What do you mean "... call MATLAB functions from within CPP_LIB ..."? How are you doing this calling exactly? If CPP_LIB is a normal C++ library, how is it trying to call mex functions? Is CPP_LIB the code that is invoking the MATLAB Engine?
The MATLAB Engine should be able to call mex routines the same as any other function. Just compile the mex routines normally and call them via engEvalString( ). But note that the architecture for this is that the MATLAB Engine is a separate process that does not share memory with your C++ code that is invoking the Engine ... meaning all variables must be deep copied back and forth, chewing up time and memory. If your variables are huge then this may not be the best approach.
Jeroen Boschma
Jeroen Boschma le 23 Juin 2023
My explanation can be a bit unclear indeed... So what I'm looking for is that a library CPP_LIB (the whole project is build with CMake and gcc) for example has a function 'void lib_function();'. Then the file that is compiled to a mex, and linked to CPP_LIB, may look like:
MexFunction::operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs)
{
....
lib_function();
....
}
That's all standard and works. But now I want to be able that 'lib_function();' in CPP_LIB can do something like:
void lib_function()
{
....
matlab::data::Array matlab_result = Matlab_engine->feval(u"rand", matlab_args);
....
}
and that's where the trouble begins, apparently because CPP_LIB is a 'standard' lib and not becoming a mex-file itself.
I know, knowing this at forehand would have lead to another setup of the project, but this is what I've to work with (legacy project....). The reason why I want to have this functionality is because I want to use highly optimized Matlab functionality like fft2 or conv2.
I'll check Nandini's answer next.

Connectez-vous pour commenter.

Réponse acceptée

Nandini
Nandini le 23 Juin 2023
Integrating the MATLAB Engine functionality within a C++ library (CPP_LIB) can be challenging due to the differences in compilation requirements and dependencies between MATLAB's MEX files and standard C++ code. The MATLAB Engine is primarily designed to be used within MATLAB or to run MATLAB code as standalone applications.
However, if you still want to call MATLAB functions from within your CPP_LIB library, one approach is to separate the MATLAB-specific code into a separate MEX file and communicate between the library and the MEX file using function calls or other suitable inter-process communication mechanisms. Here's a general outline of how you can approach this:
1. Create a separate MEX file (let's call it "mexFunction.cpp") that includes the MATLAB Engine headers and contains the code to call MATLAB functions.
cpp code-
#include "mex.h"
#include "engine.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
// Initialize MATLAB Engine
Engine *ep;
ep = engOpen(NULL);
if (ep == NULL)
{
mexErrMsgIdAndTxt("MATLAB:error", "Failed to open MATLAB Engine");
}
// Call MATLAB functions using the Engine
engEvalString(ep, "disp('Hello from MATLAB Engine!')");
// Close MATLAB Engine
engClose(ep);
}
2. Compile the "mexFunction.cpp" file to generate a MEX file using the MATLAB MEX compiler. You can do this by running the following command in MATLAB:
matlab code-
mex mexFunction.cpp -lmat -leng
3. Link the generated MEX file to your CPP_LIB library by including the MEX file in your library's build process and specifying the appropriate linking options.
4. From within the CPP_LIB library, you can call the MEX function as needed to interact with MATLAB. You can do this by using mechanisms like function pointers or other inter-process communication methods to invoke the MEX function from within your library.
Keep in mind that integrating MATLAB and C++ in this manner can be complex, and there may still be limitations and challenges due to the different compilation and runtime environments. It's important to carefully manage memory, handle errors, and ensure proper initialization and termination of MATLAB Engine instances to avoid potential issues.
Additionally, consider the licensing requirements for the MATLAB Engine and MEX files, as they may have restrictions on distribution and deployment. Consult the MATLAB documentation and MathWorks support for more information and guidance on using the MATLAB Engine in your specific scenario.
  1 commentaire
Jeroen Boschma
Jeroen Boschma le 24 Juin 2023
Thanks for the elaborate answer. I do not have enough knowledge on the process of linking libs together in a mex file, that's why I was under the impression that if, in the end, CPP_LIB is linked into the mex-file itself, there would not really be a problem to let it use the Matlab engine itself. It seems that compiling the CPP_LIB fails once including some Matlab headers because CMake is not explicitly told it will end up in a mex file anyway. I use 'matlab_add_mex' in CMAKE to generate the mex which then looks like:
add_library(CPP_LIB, cpp_lib.cpp, cpp_lib.h)
matlab_add_mex(NAME myMex
SRC myMex.h myMex.cpp
LINK_TO -static-libgcc -static-libstdc++ CPP_LIB
R2018a)
For communication between the mex-part and CPP_LIB I already thought of creating a struct with wrapper function pointers in the myMex.cpp part of the project, something like (dirty illustration...):
void disp_wrapper(const std::string& message)
{
// Get Matab engine 'ep' here.
....
// Call disp.
engEvalString(ep, "disp('" + message + "')");
}
struct MatlabWrappers {
void (*disp)(const std::string& message) = disp_wrapper;
}
and then pass the struct to any function in CPP_LIB which may need it.
But it's dirty, and in case of wanting templated functions: not possible anymore. You have to make a specialized wrapper for every flavour you might want to use (as far as I can see...).

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Call MATLAB from C dans Help Center et File Exchange

Tags

Produits


Version

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by