WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Übergabe von Parametern zwischen Matlab und C

 

Tom_57
Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 26.07.11
Wohnort: Jena
Version: R2011a
     Beitrag Verfasst am: 10.11.2011, 11:00     Titel: Übergabe von Parametern zwischen Matlab und C
  Antworten mit Zitat      
Hallo allerseits,

ich habe das Problem, dass ich C-Programme von Matlab aus aufrufen möchte. Dabei sollen von Matlab Werte in das C-Programm übergeben werden und anschließend Rechenergebnisse wieder aus Matlab in C zurückgegeben werden. Ich habe mich schon so weit eingearbeitet, dass man das mit Hilfe der Gateway-Funktion

void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])

tut. Ich habe ein einfaches Test-programm geschrieben, wobei zwei Parameter von Matlab nach C mit Hilfe der Pointer prhs[0] und prhs[1] übergeben werden. Anschließend habe ich zwei Ergebnisse mit Hilfe von plhs[0] und plhs[1] an Matlab zurückgegeben. Das funktioniert alles bestens.

Meine Frage lautet nun: Kann man auch Arrays von Matlab nach C und umgekehrt übergeben. Es ist ja ziemlich umständlich, wenn ich zum Beispiel 40 Parameter von Matlab nach C übergeben will und ich muss jeden Namen einer Variablen einzeln in den Funktionsaufruf des compilierten C-Programmes eingeben.

Beste Grüße
Thomas
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 10.11.2011, 16:58     Titel: Re: Übergabe von Parametern zwischen Matlab und C
  Antworten mit Zitat      
Hallo Tom_57,

Ja, man kann natürlich auch Arrays übergeben. Um genau zu sein, machst du das ja bereits, da Skalare ja auch Arrays der Dimension [1x1] sind.
Wenn Du mehr Details in deine Frage einfügst, kann man auch genauer antworten.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Tom_57
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 26.07.11
Wohnort: Jena
Version: R2011a
     Beitrag Verfasst am: 10.11.2011, 21:57     Titel:
  Antworten mit Zitat      
Hallo Jan,

vielen Dank für Deine Antwort.

Ich versuche morgen früh mal das Problem etwas genauer zu beschreiben.

Bis dahin

viele Grüße
Thomas
Private Nachricht senden Benutzer-Profile anzeigen
 
Tom_57
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 26.07.11
Wohnort: Jena
Version: R2011a
     Beitrag Verfasst am: 11.11.2011, 10:37     Titel:
  Antworten mit Zitat      
Hallo Jan,

ich möchte das Problem, das ich habe, noch mal etwas genauer beschreiben.
Zurzeit bin ich dabei, verschiedene Testprogramme zu schreiben, um mich in die Übergabe von Parametern zwischen Matlab und C einzuarbeiten. Ziel ist die Durchführung von Modellrechnungen, bei denen die Ausgangsdaten in Matlab eingegeben werden, die Rechnungen im C-Programm durchgeführt werden und anschließend die Rechenergebnisse im Matlab grafisch dargestellt werden. Das Ganze teste ich zurzeit an einem Programm zur linearen Regression.
Mein jetziges Programm funktioniert so, dass ich im Matlab mit dem Befehl „input“ nacheinander x- und y- Werte über die Tastatur eingebe und jeweils in ein Array eintrage. Zurzeit arbeite ich mit zwei eindimensionalen Arrays mit jeweils 20 Elementen, das heißt mit zwei Vektoren vom Typ [1,20]. Diese werden zunächst mit 20 Nullen gefüllt (initialisiert). Anschließend werden, beginnend mit den Elementen x(1) und y(1) die beiden Vektoren mit Eingabewerten gefüllt. Wenn weniger als 20 Wertepaare (x,y) eingegeben werden, sind die restlichen Elemente weiterhin gleich Null. Jetzt beginnt mein Problem: Ich habe drei Variablen, die ich an das C-Programm übergeben möchte, die beiden Arrays (Vektoren) x und y und dazu soll noch die Anzahl der Wertepaare (x,y) übergeben werden. Eigentlich würde ich gern die beiden x- und y-Arrays (Vektoren) mit dem Funktionsaufruf

[Anstieg, Achsenabschnitt]= Regression(x,y, Anzahl)

an das C-Programm übergeben. Es ist mir bisher jedoch nicht gelungen, Arrays zu übergeben. Stattdessen habe ich mir so beholfen, das ich jedes Vektorelement in eine Variable eingetragen habe und dann die einzelnen Variablen übergeben habe. Das ganze sieht etwa so aus:
x1=x(1); x2=x(2);…; x20=x(20);
y1=y(1); y2=y(2);…; y20=y(20);

Anschließend erfolgt der Funktionsaufruf
[Anstieg,Achsenabschnitt]=Regression(x1,x2,…,x20,y1,y2,…,y20,Anzahl);

Das C-Programm sieht dann etwa wie folgt aus:
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
.
.
.
/* Get arguments from MATLAB */
x1 = *(mxGetPr (prhs[0]));
x2 = *(mxGetPr (prhs[1]));
.
.
.
x20 = *(mxGetPr (prhs[19]));
y1 = *(mxGetPr (prhs[20]));
y2 = *(mxGetPr (prhs[21]));
.
.
.
y20 = *(mxGetPr (prhs[39]));
Anzahl = *(mxGetPr (prhs[40]));


Ich glaube auch, meine Rückgabe der errechneten Parameter „Anstieg“ und „Achsenabschnitt“ an Matlab ist etwas umständlich. Sie sieht etwa wie folgt aus:

/* Allocate storage place for the result */
plhs[0] = mxCreateDoubleMatrix (1,1, mxREAL);
plhs[1] = mxCreateDoubleMatrix (1,1, mxREAL);



/* Store return value */
*(mxGetPr (plhs[0])) = Anstieg;
*(mxGetPr (plhs[1])) = Achsenabschnitt;

Eleganter wäre es sicher, gleich ein [1,2]-Array (d. h. einen Vektor) zu übergeben, anstelle zweier [1,1]-Matrizen.

Die beschriebene Verfahrensweise habe ich sinngemäß aus dem Internet übertragen. Ich muss zugeben, dass ich mich mit Pointern in C noch nicht so gut auskenne. Es wäre schön, wenn mir jemand zeigen könnte, wie ich Arrays anstelle von Einzelparametern zwischen Matlab und C übergeben kann.

Beste Grüße
Thomas
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 11.11.2011, 16:59     Titel:
  Antworten mit Zitat      
Hallo Tom_57,

Code:

void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
double *x, x1, x2, x3;
double *y;
x = mxGetPr(prhs[0]);
x1 = x[0];   // Index starts at 0, not at 1 as in Matlab!!!
x2 = x[1];
x3 = x[2];

plhs[0] = mxCreateDoubleMatrix (1, 2, mxREAL);
y = mxGetPr(plhs[0]);
y[0] = x1 + x2;
y[1] = x2 / x3;
return;

Nun wird ein Vektor an die Mex-Funktion übergeben. Man muss unbedingt testen, ob er die gewünschte Anzahl von Elementen enthält (mxGetM, mxGetN, mxGetNumberOfElements), da man in C sehr leicht ausserhalb der Feld-grenzen operieren kann: x[100000] kann man einfach lesen und schreiben, auch wenn der Input-Vektor nur 3 Elemente hat.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Tom_57
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 26.07.11
Wohnort: Jena
Version: R2011a
     Beitrag Verfasst am: 14.11.2011, 17:05     Titel:
  Antworten mit Zitat      
Hallo Jan,

vielen Dank für Deine Antwort. Ich bin erst jetzt dazu gekommen, mir Deinen Vorschlag etwas näher anzusehen. Ich musste längere Zeit darüber nachdenken. Ich habe Deinen Vorschlag nicht 100%ig verstanden, mir jedoch folgendes "zusammengereimt" und damit auch ein lauffähiges Programm erzeugt:

Man muss bei der Übergabe von Arrays zwischen Matlab und C (in beiden Richtungen) immer das erste Element des von Matlab nach C zu übergebenden Arrays mit prhs[0] in Übereinstimmung bringen und das erste Element des von C nach Matlab zu übergebenden Arrays muss mit plhs[0] in Übereinstimmung gebracht werden. An diesen Adressen beginnt die Übergabe der Felder. Alle anderen Elemente der zu übergebenden Arrays befinden sich an den daran anschließenden Adressen (aufsteigend).

Nehmen wir an, ich möchte ein Array x von Matlab nach C übergeben und ein Array y con C zurück nach Matlab. x soll 1000 Elemente haben und y soll 10 Elemente haben. Dann schreibe ich

bei der Übergabe von Matlab nach C
x[0]=*(mxGetPr (prhs[0]));

und

bei der Übergabe von C nach Matlab
plhs[0] = mxCreateDoubleMatrix (1,10, mxREAL);
*(mxGetPr (plhs[0])) = y[0];

Mein Funktionsaufruf im Matlab lautet dann: Ergebnis=function(x).
Im Array mit dem Namen "Ergebnis" (10 Elemente) finde ich dann meine berechneten y[1] ... y[10] wieder. Dabei steht y[0] in Ergebnis[1], y[1] in Ergebnis[2] usw..

Habe ich das so richtig verstanden?
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 14.11.2011, 23:50     Titel:
  Antworten mit Zitat      
Hallo Tom_57,

Ja, das klingt korrekt. Probiere es mal aus.

Zitat:
Mein Funktionsaufruf im Matlab lautet dann: Ergebnis=function(x).
Im Array mit dem Namen "Ergebnis" (10 Elemente) finde ich dann meine berechneten y[1] ... y[10] wieder. Dabei steht y[0] in Ergebnis[1], y[1] in Ergebnis[2] usw..

Nur "y[1]...y[10]" muss "y[0]...y[9]" heißen, aber im folgenden Satz hast Du richtig indiziert.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Tom_57
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 26.07.11
Wohnort: Jena
Version: R2011a
     Beitrag Verfasst am: 15.11.2011, 08:32     Titel:
  Antworten mit Zitat      
Hallo Jan,

vielen Dank für die Nachricht.
Ich glaube, ich habe es jetzt verstanden. Gestern habe ich ja auch schon ein Programm zum Laufen gebracht, das so funktioniert, wie ich es beschrieben habe.
Besten Dank für die Tipps.

Vielen Dank
Thomas
Private Nachricht senden Benutzer-Profile anzeigen
 
Tom_57
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 26.07.11
Wohnort: Jena
Version: R2011a
     Beitrag Verfasst am: 15.11.2011, 11:37     Titel:
  Antworten mit Zitat      
Hallo Jan,

ich hätte nur noch einmal eine kurze Frage zum Thema Übergabe von Arrays zwischen Matlab und C.
Kann man auch mehrdimensionale Arrays zwischen Matlab und C übergeben? Ich habe gerade versucht, ein zweidimensionales Array zu übergeben und es ist fehlgeschlagen. Ich vermute, es funktioniert nicht. Man muss dann wohl die einzelnen Zeilen nacheinander in ein eindimensionales Array schreiben und auf diese Weise übergeben.

Viele Grüße
Thomas
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 15.11.2011, 12:31     Titel:
  Antworten mit Zitat      
Hallo Tom_57,

Man kann auf genau die gleiche Weise wie oben auch mehrdimensionale Arrays an C übergeben. Die Werte des Arrays stehen einfach hintereinander im Speicher, so dass es der C-Funktion bei der Übergabe(!) vollkommen egal ist, ob ein [1 x 1000], [1000 x 1] oder [100 x 10] Array übergeben wird. Beim Zugriff auf eine bestimmte Spalte ist dies dann aber wieder wichtig.

Wenn etwas "fehlgeschlagen" ist, wäre es eine gute Idee zu erklären, was das bedeutet. Gab es eine Fehlermeldung, waren die Werte anders als erwartet? Und welchen Code hast Du benutzt?

Hast Du Dir eiegtnlich schon die Beispiele angeschaut, die in der Dokumentation mitgeliefert werden? Siehe: <matlabroot>\extern\examples

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Tom_57
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 26.07.11
Wohnort: Jena
Version: R2011a
     Beitrag Verfasst am: 16.11.2011, 13:54     Titel:
  Antworten mit Zitat      
Hallo Jan,

vielen Dank für Deine letzte Nachricht. Ich bin immer noch mit dem Problem der Übergabe von Arrays zwischen Matlab und C beschäftigt, habe aber schon Fortschritte gemacht und denke, dass ich bald das Wesentliche verstanden habe. Hier nochmal eine Frage:

Ich habe mal ein Test-Matlab-Programm und ein Test MEX-Programm geschrieben, um die Übergabe eines 2-dimensionalen Arrays zu testen. Dabei erzeuge ich zunächst ein [100,5]-Array in Matlab, indem ich in jede Zelle aufsteigend Zahlen von 1 ... 500 einschreibe. Dieses Array übergebe ich dann in das MEX-Programm. In dem MEX-Programm habe ich ein Array mit dem Befehl double Array[100][5] deklariert. Ich koppele das erste Element des Arrays an prhs[0] an. Jetzt hatte ich die Hoffnung, dass ich jedes beliebige Element des übergebenen Arrays einfach der Variablen y zuweisen kann. Das klappt auch für das erste Element. Ich konnte mit dem Befehl y=Array[0][0] ohne Probleme der Variablen y das Array-Element Array[0][0] zuweisen. Dieses habe ich dann nach Matlab zurückübergeben und im Matlab den richtigen Wert ausgegeben, nämlich den Wert 1. Sobald ich aber im MEX-Programm der Variablen y ein beliebiges anderes Element des Arrays ( zum Beispiel Array[0][1] ) zuweise, funktioniert das nicht mehr. Jetzt steht in y irgendein zufälliger Wert eines nicht beschriebenen Speicherbereichs drin. Ich erhalte z. B. nach Rückübergabe im Matlab die Ausgabe Ergebnis = 2.2075e-305

Kann ich dies nicht auf die beschriebene Weise tun? Ich hatte gehofft, dass mit dem Befehl y=Array[j][k] (j=0...499, k=0...4) automatisch der Variablen y die richtige Speicherzelle des Arrays zugewiesen wird.


Hier der Quelltext meines MEX Programmes:

#include "mex.h"
#include "matrix.h"

void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
double Array[100][5];
double y;

/* "Ankoppeln" des ersten Elementes des Arrays an prhs[0]*/
Array[0][0]=*(mxGetPr (prhs[0]));


/*y bekommt den Wert des 1. Arrayelementes zugewiesen.
Bei Übergabe des Arrayelementes Array[0][0] funktioniert das,
aber z. B. bei Array[0][1] oder jedem beliebigen anderen Arrayelement
funktioniert das nicht!*/


y=Array[0][0];

/* Allocate storage place for the result */
plhs[0] = mxCreateDoubleMatrix (1,1, mxREAL);

/* y wird in der Speicheradresse plhs[0] abgespeichert für Rückübergabe */
*(mxGetPr (plhs[0])) = y;
}

Würde mich über einen kurzen Hinweis freuen.

Viele Grüße
Thomas
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 16.11.2011, 17:48     Titel:
  Antworten mit Zitat      
Hallo Tom_57,

Hast Du Dir mal die Beispiele angeschaut?

Was genau stellst Du Dir unter "Ankoppeln" eigentlich vor? Da scheint es deutliche Unklarheiten zu geben.

Code:

#include "mex.h"   // "matrix.h" wird automatisch mitgeladen...

void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
double Array[100][5];
double y;
double *InputArray;

// Hier wird der Wert des erste Elements des ersten Inputs in das erste
// Element der Matrix "Array" kopiert:
Array[0][0]=*(mxGetPr (prhs[0]));
   
// Das folgende mach genau das gleiche:
InputArray = mxGetPr(prhs[0]);
Array[0][0] = InputArray[0];

// Nun das zweite Element kopieren:
Array[0][1] = InputArray[1];
 

Ich vermute, Du hast das Kopieren eines Elementes mit einer Art "Ankoppeln" verwechselt.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Tom_57
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 26.07.11
Wohnort: Jena
Version: R2011a
     Beitrag Verfasst am: 17.11.2011, 16:03     Titel:
  Antworten mit Zitat      
Hallo Jan,

besten Dank für Deine Erläuterungen. Ich habe mich jetzt noch einmal mit Pointern beschäftigt und Deine Programmzeilen verstanden. Ich konnte jetzt auch ein lauffähiges Programm schreiben, in dem ein [100,5]-Array übergeben wird und anschließend ein beliebiges Array-Element von MEX nach Matlab zurückübergeben wird. Das funktioniert jetzt alles.

Das mit dem "Ankoppeln" war so eine bildliche Bezeichnung von mir. Ich meinte damit, dass das 1. Element des Arrays im MEX-Programm der Adresse des 1. Elementes des zu übergebenden Arrays im Matlab zugeordnet wird, dass sozusagen beide Arrays, bildlich gesprochen, übereinandergelegt werden. Ist auch egal. Jedenfalls habe ich das Ganze jetzt so weit verstanden, dass ich lauffähige Programme schreiben kann.

Nochmals besten Dank.
Viele Grüße
Thomas
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.