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}));