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

조회 수: 14 (최근 30일)
André C. D.
André C. D. 2019년 5월 3일
댓글: André C. D. 2019년 5월 15일
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!

채택된 답변

Guillaume
Guillaume 2019년 5월 7일
편집: Guillaume 2019년 5월 7일
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
Guillaume
Guillaume 2019년 5월 15일
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. 2019년 5월 15일
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!

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Sreelakshmi S.B
Sreelakshmi S.B 2019년 5월 6일
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
André C. D.
André C. D. 2019년 5월 6일
편집: André C. D. 2019년 5월 6일
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 2019년 5월 7일
"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:

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Call C++ from MATLAB에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by