Dictionary to std::unordered_map in a mex file

6 views (last 30 days)
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"}));

Accepted Answer

James
James on 22 Jul 2025
Edited: James on 23 Jul 2025
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}));

More Answers (0)

Categories

Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange

Products


Release

R2025a

Community Treasure Hunt

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

Start Hunting!