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

Matlab-DLL (mit mcc kompiliert) und Auslesen der Rückgabe

 

Andy386
Forum-Guru

Forum-Guru


Beiträge: 485
Anmeldedatum: 24.06.09
Wohnort: ---
Version: 7.1/8
     Beitrag Verfasst am: 04.10.2017, 17:37     Titel: Matlab-DLL (mit mcc kompiliert) und Auslesen der Rückgabe
  Antworten mit Zitat      
Hallo,

ich verscuhe mich grade am Einbinden einer Matlab-DLL erzeugt mit "mcc -l" in eine C++ Applikation.
Leider erhalte ich nicht den gewünschten Rückgabewert.
Anbei mein Testszenario...

MATLAB:
Code:
function out=fn1(a,b)
disp no1
%wird leider nicht in der Kommandozeile angezeigt
if isreal(a)
    out=100*a+10000*b;
elseif isinteger(a)
    out=a+10*b;
else
    out=111;
end


im batch/cmd:
Code:
mcc -l -o mlstuff fn1.m

(gekürzt, hier werden eigentlich mehrere m-Files in mlstuff gepackt...

in C++:
Code:
  mclInitializeApplication(NULL,0);
   mlstuffInitialize();
   
   mxArray* a=int2mx((int)5);
   mxArray* b=int2mx((int)7);

   mxArray* outInit=mxCreateDoubleScalar(0);
   mxArray* outOf=NULL;
//irgendwo habe ich mal gesehen, dass jemand das mxArray mit NULL initalisiert hat...  

   double* ptr_realo=mxGetPr(outInit);
   double realo=*ptr_realo;
   void* ptr_datao=mxGetData(outInit);
   double datao=*ptr_datao;
   // ptr_realo und ptr_datao zeigen auf die selben Speicheradressen.

   ret=mlfAndy1(1,&outOf, a, b);  
   ret=mlfAndy1(1,&outInit, a, b);
   
   ptr_realo=mxGetPr(outInit);
   realo=*ptr_realo;
   ptr_datao=mxGetData(outInit);
   datao=*ptr_realo;
//HAUPTPROBLEM: realo und datao zeigen noch immer auf 0!

   ptr_realo=mxGetPr(outOf);
//Absturz, outOf zeigt immer noch auf Null...
   realo=*ptr_realo;
   ptr_datao=mxGetData(outOf);
   datao=*ptr_realo;

 



Weiß jemand Rat?
_________________

Ich hasse es wenn die Leute Fragen stellen, man dann versucht sich Mühe zu geben, und diejenigen ihren Thread nie wieder besuchen...
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: 04.10.2017, 19:13     Titel: Re: Matlab-DLL (mit mcc kompiliert) und Auslesen der Rückga
  Antworten mit Zitat      
Hallo Andy386,

Ich verstehe das Problem noch nicht.
Was macht der Code denn überhaupt? Wieso wird der Inhalt von realo immer wieder überschrieben?
Code:
mxArray* outOf=NULL;
double* ptr_realo=mxGetPr(outInit);
double realo=*ptr_realo;   % Nummer 1

ret=mlfAndy1(1,&outOf, a, b);     % Wird outOf hier definiert oder nicht?
   
ptr_realo=mxGetPr(outInit);  % ptr_reaqlo wird wieder überschrieben
realo=*ptr_realo;        % realo wird wirde überschrieben

//HAUPTPROBLEM: realo und datao zeigen noch immer auf 0!
% Nein, realo und datao sind keine Pointer, also zeigen sie auch nirgendwo hin.
% Sondern sie haben beide einen Wert.

ptr_realo=mxGetPr(outOf);  % Wieder überschrieben
//Absturz, outOf zeigt immer noch auf Null...

realo=*ptr_realo;   % Wieder überschrieben
 


mxGetPr(outOf) muss scheitern, wenn outOf immer noch NULL ist. Ist es immer noch NULL? Dann muss Du das ändern.

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

Forum-Guru

Forum-Guru


Beiträge: 485
Anmeldedatum: 24.06.09
Wohnort: ---
Version: 7.1/8
     Beitrag Verfasst am: 05.10.2017, 10:03     Titel:
  Antworten mit Zitat      
Sorry für die nicht vorhandenen Erklärungen...
Der C-Code dient eigentlich nur dazu, die einfache Funktion "Andy1" aus Matlab bzw. dem kompilierten in der DLL aufzurufen.

Dafür wird erst alles initialisiert und dann werden a und b mit int2mx erstellt. Shocked mea culpa - da ist ein Define:
Code:
#define int2mx mxCreateDoubleScalar

Das funktiniert soweit schon. Jetzt sollen a und b in die Funktion Andy1. Dazu nutze ich die Deklaration aus dem Headerfile, welches mcc mir auswirft.

realo und datao sind dann nur zum Anzeigen der Werte da, die in den mxArray* stehen und werden daher mehrfach überschrieben.
Im Grunde finden die nur im Debugging Beachtung.

Irgendwie finde ich es Schade, dass Mathworks kein Beispiel liefert, wie man die mit mcc erstellten DLLs in ein C++ Programm einbindet Sad


Code:
mxArray* outOf=NULL;
double* ptr_realo=mxGetPr(outInit);
double realo=*ptr_realo;   % Nummer 1

Das funktioniert soweit. realo ist "0", also wie mit mxCreateDoubleScalar(0) definiert.

Code:
ret=mlfAndy1(1,&outOf, a, b);     % Wird outOf hier definiert oder nicht?

Ich hoffe mal, dass outOf hier definiert wird - das ist zumindest die Funktion aus der headerdatei die mcc ausgespuckt hat...
Zitat:
//% aus dem header:
LIB_mlstuff_C_API
bool MW_CALL_CONV mlfAndy1(int nargout, mxArray** out, mxArray* a, mxArray* b)
{
return mclMlfFeval(_mcr_inst, "Andy1", nargout, 1, 2, out, a, b);
}




Code:
ptr_realo=mxGetPr(outInit);  % ptr_reaqlo wird wieder überschrieben
realo=*ptr_realo;        % realo wird wirde überschrieben
 

Ja, das ist so geplant. Wobei das Überschreiben von ptr_realo nicht zwingend nötig sein muss...


Code:
//HAUPTPROBLEM: realo und datao zeigen noch immer auf 0!
% Nein, realo und datao sind keine Pointer, also zeigen sie auch nirgendwo hin.
% Sondern sie haben beide einen Wert.
 

Stimmt! realo und datao sind 0.
_________________

Ich hasse es wenn die Leute Fragen stellen, man dann versucht sich Mühe zu geben, und diejenigen ihren Thread nie wieder besuchen...
Private Nachricht senden Benutzer-Profile anzeigen
 
Andy386
Themenstarter

Forum-Guru

Forum-Guru


Beiträge: 485
Anmeldedatum: 24.06.09
Wohnort: ---
Version: 7.1/8
     Beitrag Verfasst am: 05.10.2017, 10:07     Titel:
  Antworten mit Zitat      
Jan S hat Folgendes geschrieben:

mxGetPr(outOf) muss scheitern, wenn outOf immer noch NULL ist. Ist es immer noch NULL? Dann muss Du das ändern.

Gruß, Jan

Ja, outOf ist immernoch NULL. Ich hab das mit outOf=NULL (ein paar Zeilen drüber) irgendwie so in einem Script gelesen, indem auch auf eine von Matlabs mcc erstellte DLL zugegriffen wird. Aber egal, ob ich dem Return einen Wert zuweise oder nicht, weder dieser Wert noch der Wert des Zeigers scheint sich zu ändern... Crying or Very sad
_________________

Ich hasse es wenn die Leute Fragen stellen, man dann versucht sich Mühe zu geben, und diejenigen ihren Thread nie wieder besuchen...
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: 05.10.2017, 19:55     Titel:
  Antworten mit Zitat      
Hallo Andy386,

So weit ich es verstehe, ist das eigentliche Problema also hier:
Code:
mxArray* outOf = NULL;
ret = mlfAndy1(1, &outOf, a, b);

Danach sollte outOf auf ein Matlab-Array zeigen, tut es aber nicht, sondern es ist immer noch NULL. Richtig?
Dann liegt das Problem also in mlfAndy1. Dann schaue doch mal dort nach, wieso hier nichts zugewiesen wird.

Ob Du den Pointer zunächst mit NULL initialisierst oder nicht, ist ein kosmetischer Unterschied. Es hilft nur, nicht aus versehen einen Wert zu verwenden, der dort zufällig im Speicher stand. "mxArray* outOf" tut es aber auch zuverlässig.

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

Forum-Guru

Forum-Guru


Beiträge: 485
Anmeldedatum: 24.06.09
Wohnort: ---
Version: 7.1/8
     Beitrag Verfasst am: 06.10.2017, 14:04     Titel:
  Antworten mit Zitat      
Danke für die Antwort.

Ich glaub ich hätte mir mal die Returnwerte angucken sollen...

mlstuffInitialize() liefert schon false zurück. Da vermute ich dann den Fehler d.h. in einem fehlerhaften pragma bzw. fehlendem Verlinken der Libs.

reingesachaut zeigt path_to_dll auf die exe (bzw. hat trotz der Bennenung als Pfad "[Anwendungsname].exe" drin stehen...)

Code:

LIB_mlstuff_C_API
bool MW_CALL_CONV mlstuffInitializeWithHandlers(
    mclOutputHandlerFcn error_handler,
    mclOutputHandlerFcn print_handler)
{
    int bResult = 0;
  if (_mcr_inst != NULL)
    return true;
  if (!mclmcrInitialize())
    return false;
  if (!GetModuleFileName(GetModuleHandle("mlstuff"), path_to_dll, _MAX_PATH))
    return false;
    {
        mclCtfStream ctfStream =
            mclGetEmbeddedCtfStream(path_to_dll);
        if (ctfStream) {
            bResult = mclInitializeComponentInstanceEmbedded(   &_mcr_inst,
                                                                error_handler,
                                                                print_handler,
                                                                ctfStream);
            mclDestroyStream(ctfStream);
        } else {
            bResult = 0;
        }
    }  
    if (!bResult)
    return false;
  return true;
}



Die Anwendung die läuft greift auf eine DLL zu, welche die mcc-DLL einbindet.
Keine Ahnung auf was path_to_dll verweisen soll...
_________________

Ich hasse es wenn die Leute Fragen stellen, man dann versucht sich Mühe zu geben, und diejenigen ihren Thread nie wieder besuchen...
Private Nachricht senden Benutzer-Profile anzeigen
 
Andy386
Themenstarter

Forum-Guru

Forum-Guru


Beiträge: 485
Anmeldedatum: 24.06.09
Wohnort: ---
Version: 7.1/8
     Beitrag Verfasst am: 11.10.2017, 17:30     Titel:
  Antworten mit Zitat      
Sooo...
zuersteinmal hatte ich vergessen die aktuelle DLL auch in den Ausführungspfad zu setzen. nachdem das erledigt war, blieb aber immer noch outOf (egal ob nun initalisiert oder nicht) genau so, wie ich es reingeschoben habe.

am Ende war es ein Problem beim erstellen:
wenn ich aus
Code:

mcc -B csharedlib:mlsharedlib -T link:lib andy1.m ...
 


Code:
mcc -B csharedlib:mlsharedlib andy1.m ...

gemacht habe, bin ich zu meinen erwarteten Ergebnissen gekommen...
_________________

Ich hasse es wenn die Leute Fragen stellen, man dann versucht sich Mühe zu geben, und diejenigen ihren Thread nie wieder besuchen...
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.