2016-05-29 8 views
1

Ich habe eine Funktion, die ich als eine MATLAB-Mex-Datei schreibe. Diese Funktion muss MEX verwenden, da sie mit einer Hardware in C++ verbunden ist. Es gibt viele Optionen, die eingestellt werden können, und ich möchte eine containers.Map verwenden, um sie zu übergeben. (Ansonsten würde ich eine große Anzahl von Funktionsparametern benötigen.)Gibt es eine Möglichkeit, Werte aus einer Map in einer MATLAB-Mex-Datei zu erhalten?

Ich sehe keine Möglichkeit, auf den Map-Operator zuzugreifen, der Werte mithilfe von Schlüsseln abruft. Ich habe versucht, mexCallMATLAB, aber meine verschiedenen Ansätze fehlgeschlagen. Gibt es eine Möglichkeit, dies zu tun?

Ich dachte, vielleicht auf Karte Operator subsref implementiert, aber dies nicht gelingt in MATLAB, so vermute ich, das Äquivalent in einer mex-Datei fehlschlagen würde, auch:

dict = containers.Map('foo', 3) 
subsref(dict, struct('type', '.', 'subs', 'foo')) 
+2

Können Sie sich eine Struktur verwenden? Dann könnten Sie 'mxGetField' und andere verwandte Funktionen verwenden. – horchler

+0

Vielleicht - ich untersuche das jetzt. –

+0

Ja - das funktioniert für mich. Vielen Dank! Ich denke, ich werde diese Frage offen lassen, da jemand vielleicht noch eine Antwort auf Maps haben möchte. –

Antwort

0

Upvote für @ nirvana-msu, um mich auf die richtige Spur zu bringen. Auch, dank @horchler für den Vorschlag, dass die Verwendung einer struct stattdessen eine bessere Idee ist. Hier ist, wie ein containers.Map in C++ für den Zugriff nach einer in MATLAB mit einem Feld machen foo genannt:

#include <mex.h> 

void mexFunction(int nlhs, mxArray *plhs[], 
       int nrhs, const mxArray *prhs[]) { 
    mxArray *args[2]; 
    args[0] = const_cast<mxArray*>(prhs[0]); 

    const char **fields = (const char **) mxCalloc(2, sizeof(*fields)); 
    fields[0] = "type"; 
    fields[1] = "subs"; 

    args[1] = mxCreateStructMatrix(1, 1, 2, fields); 
    auto typeStr = mxCreateString("()"); 
    mxSetField(args[1], 0, "type", typeStr); 
    auto mapKey = mxCreateString("foo"); 
    mxSetField(args[1], 0, "subs", mapKey); 

    mxArray *output; 
    mexCallMATLAB(1, &output, 2, args, "subsref"); 
    mexPrintf("%f\n", mxGetScalar(output)); 
    mxDestroyArray(args[1]); 
    mxFree(fields); 
} 
2

Sie verwenden falsche 'type' in subsref - verwenden Sie stattdessen '()', da Sie auf die Werte unter Verwendung der () Notation in containers.Map zugreifen und keine Punktnotation wie in Strukturen verwenden. Die folgende Methode funktioniert:

dict = containers.Map('foo', 3); 
subsref(dict, struct('type', '()', 'subs', 'foo')) 

ans = 
    3 

Als Randbemerkung, ich bin nicht wirklich sicher, ob containers.Map ist der beste Weg. Ihr C++ Code wäre viel sauberer, wenn Sie explizite Setter-Methoden erstellen. Wenn zu viele Eigenschaften vorhanden sind, kann Builder design pattern hilfreich sein.