Dictionary to std::unordered_map in a mex file

조회 수: 5 (최근 30일)
James
James 2025년 7월 21일
편집: James 2025년 7월 23일
I am using some c++ code with mex. I would like to pass in a dictionary of parameters, do some computation and create some vectors, and then return the results as a dictionary. Something like the following:
// test_mex.cpp
#include "mex.h"
void mexFunction(int N_output, mxArray *output[], int N_input, const mxArray *input[]) {
// Check input
if (N_input != 1) {
mexErrMsgIdAndTxt("MyClass:InvalidInput", "One input required.");
}
if (!mxIsClass(input[0], "dictionary")) {
mexErrMsgIdAndTxt("MATLAB:invalidInput", "Input must be a dictionary.");
}
// Convert to a std::unordered_map
std::unordered_map<std::string, double> params = input[0];
// Compute
std::unordered_map<std::string, std::vector<double>> out;
out["C"] = std::vector<double>(params["A"], 1.0);
// Convert back to a dictionary and return
output[0] = out;
}
Called with:
mex test_mex; test_mex(dictionary(["A", "B"], {100, "test"}));

채택된 답변

James
James 2025년 7월 22일
편집: James 2025년 7월 23일
You can parse a dictionary as input but must return a mxArray:
// test.cpp
#include "mex.h"
#include <variant>
#include <string>
#include <vector>
using dictionary = std::unordered_map<std::string, std::variant<double, std::string, bool, std::vector<double>>>;
using results = std::unordered_map<std::string, std::vector<double>>;
dictionary dictionaryToUnorderedMap(const mxArray *dict)
{
dictionary res;
// Ensure it's a dictionary type
if (!mxIsClass(dict, "dictionary"))
{
mexErrMsgIdAndTxt("MEX:InvalidType", "Expected a MATLAB 'dictionary' object.");
}
// Get keys
mxArray *keys;
mexCallMATLAB(1, &keys, 1, const_cast<mxArray **>(&dict), "keys");
const mxArray *keyCell = keys;
// Get values
mxArray *values;
mexCallMATLAB(1, &values, 1, const_cast<mxArray **>(&dict), "values");
const mxArray *valueCell = values;
mwSize nKeys = mxGetNumberOfElements(keys);
for (mwSize i = 0; i < nKeys; ++i)
{
// Extract key
const mxArray *keyElement = mxGetCell(keyCell, i);
if (!mxIsChar(keyElement))
{
mexErrMsgIdAndTxt("MEX:NonStringKey", "Dictionary key must be a string.");
}
char *keyStr = mxArrayToString(keyElement);
std::string key(keyStr);
// Extract value - double, string, and bool supported
const mxArray *valueElement = mxGetCell(valueCell, i);
// mexPrintf("Key: %s, Value:", keyStr);
if (mxIsDouble(valueElement))
{
if (mxGetNumberOfElements(valueElement) == 1)
{
// single double value
double value = mxGetScalar(valueElement);
res[key] = value;
// mexPrintf(" %f\n", value);
}
else
{
// vector of doubles
std::vector<double> vec(mxGetNumberOfElements(valueElement));
for (mwSize i = 0; i < mxGetNumberOfElements(valueElement); ++i)
{
vec[i] = mxGetPr(valueElement)[i];
// mexPrintf(" %f", vec[i]);
}
res[key] = vec;
// mexPrintf(" vector of size %zu\n", vec.size());
}
}
else if (mxIsChar(valueElement))
{
// string
char *value = mxArrayToString(valueElement);
res[keyStr] = std::string(value);
mxFree(value); // Free the string memory
// mexPrintf(" %s\n", value);
}
else if (mxIsLogical(valueElement))
{
// bool
bool value = mxIsLogicalScalarTrue(valueElement);
res[keyStr] = value;
// mexPrintf(" %s\n", value ? "true" : "false");
}
else
{
mexErrMsgIdAndTxt("MEX:UnsupportedType", "Unsupported value type in dictionary.");
}
}
return res;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
// Check input
if (nrhs != 2)
{
mexErrMsgIdAndTxt("MyClass:InvalidInput", "Two inputs required.");
}
dictionary init_parameters = dictionaryToUnorderedMap(prhs[0]);
results res;
res["banana"] = std::vector<double>(std::get<int>(init_parameters["N"]), 1.0);
res["apple"] = std::vector<double>(std::get<int>(init_parameters["N"]), 2.0);
plhs[0] = mxCreateDoubleMatrix(2, res["banana"].size(), mxREAL);
double *data = mxGetPr(plhs[0]);
int N_rows = 2;
for (mwSize i = 0; i < res["banana"].size(); ++i)
{
data[0 + i * N_rows] = res["banana"][i];
}
for (mwSize i = 0; i < res["apple"].size(); ++i)
{
data[1 + i * N_rows] = res["apple"][i];
}
}
Call with:
mex test_mex; test_mex(dictionary({'N'}, {100}));

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Write C Functions Callable from MATLAB (MEX Files)에 대해 자세히 알아보기

태그

제품


릴리스

R2025a

Community Treasure Hunt

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

Start Hunting!

Translated by