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 Center および File ExchangeWrite 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