Dictionary to std::unordered_map in a mex file

8 次查看(过去 30 天)
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