How do I pass a string from a C++ Mex file to the MATLAB workspace?

16 Ansichten (letzte 30 Tage)
I am trying to pass a string from a C++ Mex file I am working on to the MATLAB workspace for plotting purposes. It is a fairly complicated program, but all I want to do is pass a std::string in my MexFunction (which I defined as "var") to the MATLAB workspace. This is the important part of the code:
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using namespace matlab::engine;
using namespace std;
using matlab::mex::ArgumentList;
// "some code here" //
class MexFunction : public matlab::mex::Function{
public:
void operator()(ArgumentList outputs, ArgumentList inputs){
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
ArrayFactory factory;
// "more code here" //
for(int i = 0; i < 100; i++){
std::vector<ToolData> toolData = apiSupportsBX2 ? capi.getTrackingDataBX2() : capi.getTrackingDataBX();
for (int i = 0; i < toolData.size(); i++)
{
std::string var = toolDataToCSV(toolData[i]);
std::cout << var << std::endl;
// Pass "var" to MATLAB here //
}
usleep(5000);
}
matlabPtr->eval(u"printData = true");
// "more code here" //
std::cout << "Press Enter to continue...";
std::cin.ignore();
}
};
I'm fairly new to C++/MATLAB-implementations and don't have that much experience with Mex file programming, so thanks in advance!

Akzeptierte Antwort

Guillaume
Guillaume am 7 Mai 2019
Bearbeitet: Guillaume am 7 Mai 2019
matlab:engine::setvariable seems to be the function to do that. With your original C++ code (not the C interface)
matlabPtr->setVariable(u"variablename", var); //%don't use var as variable name in matlab. It's the variance function.
Untested. I've never used the C++ interface.
  3 Kommentare
Guillaume
Guillaume am 15 Mai 2019
I'm assuming this is a data type conversion problem, but I am not familiar with the way MATLAB handles its data types.
I would say it's a purely C++ problem. You try to call a C++ function with arguments that don't match the function signature. In particular, as documented in the link in my answer, the second argument to setVariable has to be of type matlab::data::Array.
You can easily construct that object as demonstrated here:
matlab::data::ArrayFactory factory;
matlabPtr->setVariable(u"variablename", factory.createCharArray(var)); //assuming var is std::string
André C. D.
André C. D. am 15 Mai 2019
EDIT: I managed to make it work now, I had forgotten to use factory.createCharArray() before setVariable and now it works.
So at the end, I used the original code and added this:
Array str = factory.createCharArray(var); //var is of type std::string
matlabPrt->setVariable(u"StringName",str);
Thank you for the tip!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Sreelakshmi S.B
Sreelakshmi S.B am 6 Mai 2019
You can convert var to an mxArray and use 'engPutVariable' to write the mxArray into the Matlab Engine Worspace.You can find details about using this function in C and Fortran at this link: https://in.mathworks.com/help/matlab/apiref/engputvariable.html
This will work with C++ too.
  2 Kommentare
André C. D.
André C. D. am 6 Mai 2019
Bearbeitet: André C. D. am 6 Mai 2019
Hi, thanks for the response. The problem with using engPutVariable, is that whenever I include "engine.h", I get the following error when compiling the Mex file:
#error Using MATLAB Data API with C Matrix API is not supported
I am assuming this is because I have included "mex.hpp" and/or "mexAdapter.hpp". How should I go about solving this problem?
EDIT:
I have replaced the header files "mex.hpp" and "mexAdapter.hpp" with only "engine.h" and used the same method as explained in engdemo.c ('extern/examples/eng_mat/engdemo.c') and now have the following code:
#include "engine.h"
#pragma comment(lib,"libmat.so")
#pragma comment(lib,"libmx.so")
#pragma comment(lib,"libmex.so")
#pragma comment(lib,"libeng.so")
// "Code" //
int main(){
Engine *ep;
mxArray *pointer;
for(int i = 0; i < 100; i++){
std::vector<ToolData> toolData = apiSupportsBX2 ? capi.getTrackingDataBX2() : capi.getTrackingDataBX();
for (int i = 0; i < toolData.size(); i++)
{
std::string var = toolDataToCSV(toolData[i]); //toolDataToCSV returns string
std::cout << var << std::endl;
char ch[var.size() + 1];
strcpy(ch, var.c_str()); //conversion from std::string to char
pointer = mxCreateString(ch);
memcpy((void *)mxGetPr(ch), (void *)ch, sizeof(ch));
engPutVariable(ep, "ch", ch);
}
usleep(10000);
}
mxDestroyArray(pointer);
engEvalString(ep, "close;");
return 0;
}
And now the issues I get are:
cannot convert 'char*' to 'const mxArray* {aka const mxArray_tag*}' for argument '1' to 'double* mxGetPr(const mxArray*)';
cannot convert 'char*' to 'const mxArray* {aka const mxArray_tag*}' for argument '3' to 'int engPutVariable(ep, "ch", ch);
Using mxGetString instead of mxGetPr also leads to a smilar data conversion issue.
Sreelakshmi S.B
Sreelakshmi S.B am 7 Mai 2019
"The MATLAB Data API supports modern C++ features and is not compatible with the C Matrix API" ------- as taken from the official documentation page.This is why the initial error is happening.
You can try using 'setVariable' instead.This link has more details on how to go about doing that:

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Call C++ from MATLAB finden Sie in Help Center und File Exchange

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by