Portierungsproblem (C-Builder -> gcc)



  • Guten Tag,

    ich bin zur Zeit dabei eine Win32-Anwendung auf das QT Framework unter Linux zu portieren und bin auf folgendes Problem gestoßen:

    ..
    // Gauss Fit Funktion
    void abc::FitGauss(double x, std::vector<double> ca, double &y, std::vector<double> &dyda, int na)
    {
    ....
    }
    ..
    ..
    vector<double> abc::showDispersion(int div,TChartSeries *Series1,TChartSeries *Series2)
    {
     TDoublePointS point;
     vector<TDoublePointS> daten;
     vector<int> vario;
     vector<double> para;
    ..
    ..
    // Fitting des Gauss
     TLMFit GaussFit(daten,para,vario,&FitGauss);
     GaussFit.Fit();
     while ((GaussFit.Alamda() < 10000000) && (iter < 1000) )
     {
      GaussFit.Fit();
      iter++;
     }
     dispersion.clear();
     dispersion   = GaussFit.ReturnParam();
    ..
    }
    

    Ergibt folgende Fehlermeldung unter KDevelop 3.5.3 (QT 3.3):

    abc.cpp:1300: error: no matching function for call to 'TLMFit::TLMFit(
    std::vector<TDoublePointS, std::allocator<TDoublePointS> >&,
    std::vector<double, std::allocator<double> >&,
    std::vector<int,std::allocator<int> >&,
    void (abc::*)(
                  double,
                  std::vector<double, std::allocator<double> >,
                  double&, 
                  std::vector<double, std::allocator<double> >&, int)
                 )'
    
    SilibLMFit.h:114: note: TLMFit::TLMFit(
    std::vector<TDoublePointS, std::allocator<TDoublePointS> >,
    std::vector<double, std::allocator<double> >,
    std::vector<int, std::allocator<int> >,
    void (*)(double, 
             std::vector<double,std::allocator<double> >,
             double&,
             std::vector<double,std::allocator<double> >&,
             int))
    
    SilibLMFit.h:102: note: TLMFit::TLMFit(const TLMFit&)
    

    Die Fehlermeldung ist eigentlich etwas länger, da die Klasse viele Konstruktoren enthält die ich jedoch nicht verwenden möchte.

    Der Compiler hängt im ersten Teil der Fehlermeldung hinter jeden Paramter >&, was ich mir schonmal nicht erklären kann (deshalb findet er wohl nicht den richtigen Konstruktor), da ich Objekt genau so erzeuge wie im C-Builder unter Windows. Ich habe auch verschiedene Varianten der Objekterzeugung ausprobiert. Könnte das Problem mit den template-Klassen zusammen hängen?

    Ich bin dankbar für jeden Tip!

    Gruß,
    Box123

    Edit: Falscher Konstruktor...



  • Mal ganz ehrlich:
    Wirst du selbst aus dem von dir geposteten Stück Quellcode schlau?

    1. Die Funktionsnamen passen nicht, entweder du hast Änderungen nicht komplett durchgezogen oder falsche Codeteile gepostet.

    2. Der Compiler moniert jedenfalls einen Konstruktur, die Funktion FitGauss ist aber kein Konstruktor also was soll uns die bringen?

    Übrigens: Qt3 ist veraltet und es wird davon abgeraten damit weiterhin Applikationen zu entwickeln.



  • Hallo rean,

    danke für Deine Antwort.

    Ich kann leider nicht alles einfügen, da die Methoden zu umfangreich sind. Ich habs überarbeitet, hoffe es ist nun klarer. FitGauss ist nur wegen der Parameter drin (wird doch mit übergeben, bei der Objekterzeugung von TLMFit).

    Wenn Du willst kann ich auch den Konstruktor posten, aber was innerhalb des Konstruktor gemacht wird, dürfte, was die Parameterübergabe angeht, doch egal sein, oder?

    Gruß,
    Box123



  • Ja jetzt ist es schon um einiges klarer.
    Die Defintion des Konstruktors wäre sicher gut.



  • Ok, hier ist die gesamte Klassendeklaration:

    class TLMFit{
    public:
       TLMFit (  vector<TDoublePointS> Points,
      			     vector<double> Param,
                                 vector<int> UsedVar,
                                 void (*CfuncP)(double x, vector<double> ca,
                                 double &y, vector<double> &dyda, int na));
    
       TLMFit (vector<TDoublePointS*> Points,
      			     vector<double> Param,
                                 vector<int> UsedVar,
                                 void (*CfuncP)(double x, vector<double> ca,
                                 double &y, vector<double> &dyda, int na));
    
       TLMFit  (vector<double> Xdata,
                                  vector<double> Ydata,
                                  vector<double> Param,
                                  vector<double> Sigma,
                                  vector<int> UsedVar,
                                  void (*CfuncP)(double x, vector<double> ca,
                                  double &y, vector<double> &dyda, int na));
    
       TLMFit  (vector<double> Xdata,
                                  vector<double> Ydata,
                                  vector<double> Param,
                                  vector<double> Sigma,
                                  void (*CfuncP)(double x, vector<double> ca,
                                  double &y, vector<double> &dyda, int na));
    
       virtual ~TLMFit (){};
    
      void Fit();
    
      // Accessors:
      vector< vector<double> >	Alpha() const {return alpha;};
      vector< vector<double> > 	Covar() const {return covar;};
      double Chisq() const {return chisq;};
      vector<double> Param() const {return a;};
      int Ndata() const {return ndata;};
      int Nparam() const {return nparam;};
      double Alamda() const {return alamda;};
      vector<double> ReturnParam() const;
      double chisq, alamda;
    
      void SetParam (vector<double> Param){a = Param;}
    
    private:
      bool gaussj(vector< vector<double> > &a, int m, vector< vector<double> > &b, int n);
      void covsrt(int mfit);
      void mrqcof(vector<double> &a, vector< vector<double> > &alpha, vector<double> &beta);
      void mrqmin(void);
      inline void SWAP (double &a, double &b) {double temp = a; a = b; b = temp;};
    
      vector<double> x, y, a, sig;                 //x-, y-Values, Fit-Parameters a, Sigmas
      vector<int> ia;                              //Use Fit-Parameter for fit (1) or not (0)
      vector< vector<double> > covar, alpha;       //Covarianz-Matrix
      int ndata, nparam;                           //Number of Points, Number of Parameters
      void (*funcP)(double x, vector<double> ca, double &y, vector<double> &dyda, int na);
    };
    

    und der Konstruktor den ich verwenden möchte:

    TLMFit::TLMFit (vector<TDoublePointS> Points,
      	             vector<double> Param,
                         vector<int> UsedVar,
                         void (*CfuncP)(
                                        double x,
                                        vector<double> ca,
                                        double &y,
                                        vector<double> &dyda,
                                        int na)
                                        )
    
    {
    
      int mfit = 0;
      chisq = 0;
      alamda = -1;
    
      ndata  = Points.size();
      nparam = Param.size();
    
      x.resize(ndata);
      y.resize(ndata);
      sig.resize(ndata);
      for(int i = 0; i < ndata; i++) {
        x[i]   = Points[i].x;
        y[i]   = Points[i].y;
        sig[i] = Points[i].Sigma;
      }
    
      a.resize(nparam);
      ia.resize(nparam);
      for(int i = 0; i< nparam; i++) {
        a[i] = Param[i];
        ia[i] = UsedVar[i];
        if (ia[i]) mfit++;
      }
    
      alpha.resize(mfit);
      covar.resize(mfit);
      for (int i = 0; i<mfit;i++) {
         covar[i].resize(mfit);
         alpha[i].resize(mfit);
      }
    
      funcP = CfuncP;
    }
    

  • Administrator

    @Box123,
    Was ist abc ? Ist abc ein namespace oder eine Klasse?

    Grüssli



  • Hallo Dravere,

    ist die Klasse aus denen die Funktionen showDispersion und FitGauss stammen.

    Gruß,
    Box123



  • Wenn abc eine Klasse ist ist ein Problem auf alle Fälle mal folgendes:

    Der this-Zeiger ist bei Memberfunktionen immer vorborgenes 1. Element.
    D.h. dass deine Definition nicht stimmt.
    Entweder du machst FitGauss(...) static oder änderst deinen Konstruktor wie folgt ab:

    TLMFit (  vector<TDoublePointS> Points,
                       vector<double> Param,
                                 vector<int> UsedVar,
    							 void (abc::/*hier!*/*CfuncP)(double x, vector<double> ca,
                                 double &y, vector<double> &dyda, int na))
    

    Ob die static-Lösung was für dich ist musst du gucken, die abc:: -Lösung hat den Nachteil dass du dann nurnoch Memberfunktionen von abc übergeben kannst.

    [EDIT]
    Dravere hat natürlich recht.
    Die zweite Lösung bringt so nichts.


  • Administrator

    Tjo, dann ist es kein Wunder, dass es nicht funktioniert. Ein freier Funktionszeiger und ein Methodenzeiger sind nicht gleich. Methodenzeiger brauchen nämlich immer noch ein Objekt, damit sie aufgerufen werden können. Du kannst ein Methodenzeiger nicht einem Zeiger für eine freie Funktion zuweisen, keine Chance!

    Es gibt mehrere Möglichkeiten, wie du das lösen könntest, aber da müsste man ein wenig mehr Informationen darüber haben, was du machen möchtest. Welche Methode von welchem Objekt soll zum Beispiel aufgerufen werden? Vom aktuellen?

    Grüssli



  • So, durch Euch bin ich auf die Lösung gekommen. Ich war einfach schludrig bei der Portierung: FitGauss war gar keine Methode der Klasse abc, sondern eine ganz normale Funktion die halt in der cpp-Datei zwischen den abc-Methoden gemischt war (ist halt nicht mein Quellcode, grmbl). Ich hab das nicht gemerkt und FitGauss der Klasse abc hinzugefügt! Dadurch entstand die Problematik. Ohne Draveres Hinweis das sich Methodenzeigern von Funktionszeigern unterscheiden, wär ich wohl nicht drauf gekommen (wusste ich vorher auch gar nicht.. :/).

    Er kompiliert jetzt fehlerfrei durch! Testen kann ich aber erst am Montag, dazu brauche ich mein Hardware-System.

    Danke schön für die Hilfe.

    Gruß,
    Box123


Anmelden zum Antworten