Problem beim Zugriff auf statische Bibliothek, __clrcall und __cdecl



  • Hallo Forum,

    ich bin gerade dabei ein Programm zu aktualisieren. In diesem benutze ich eine statische Bibliothek, welche auch aktualisiert wurde. Also hab ich diese ebenfalls neu compiliert und erhalte jetzt beim Erstellen den Fehler C2664

    error C2664: 'dlevmar_bc_der': Konvertierung des Parameters 1 von 'void (__clrcall *)(double *,double *,int,int,void *)' in 'void (__cdecl *)(double *,double *,int,int,void *)' nicht möglich

    Ich kann mir im Moment aber nicht erklären, woher der Fehler kommt.

    Folgende zusätzliche Information sind bestimmt sinnvoll:
    Sowohl mein Programm als auch die Bibliothek sind mit dem Schalter /clr und der Aufrufkonvention __cdecl (/Gd) compiliert. Die Header-Datei der Bibliothek wird entsprechend zu Beginn meines Programmes mittel #inlude eingebunden. Die Header-Datei sieht dabei wie folgt aus (Auszug, komplett gibt es sie hier: http://www.ics.forth.gr/~lourakis/levmar/index.html):

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define FABS(x) (((x)>=0.0)? (x) : -(x))
    
    /* work arrays size for ?levmar_der and ?levmar_dif functions.
     * should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes
     */
    #define LM_DER_WORKSZ(npar, nmeas) (2*(nmeas) + 4*(npar) + (nmeas)*(npar) + (npar)*(npar))
    #define LM_DIF_WORKSZ(npar, nmeas) (4*(nmeas) + 4*(npar) + (nmeas)*(npar) + (npar)*(npar))
    
    /* work arrays size for ?levmar_bc_der and ?levmar_bc_dif functions.
     * should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes
     */
    #define LM_BC_DER_WORKSZ(npar, nmeas) (2*(nmeas) + 4*(npar) + (nmeas)*(npar) + (npar)*(npar))
    #define LM_BC_DIF_WORKSZ(npar, nmeas) LM_BC_DER_WORKSZ((npar), (nmeas)) /* LEVMAR_BC_DIF currently implemented using LEVMAR_BC_DER()! */
    
    /* work arrays size for ?levmar_lec_der and ?levmar_lec_dif functions.
     * should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes
     */
    #define LM_LEC_DER_WORKSZ(npar, nmeas, nconstr) LM_DER_WORKSZ((npar)-(nconstr), (nmeas))
    #define LM_LEC_DIF_WORKSZ(npar, nmeas, nconstr) LM_DIF_WORKSZ((npar)-(nconstr), (nmeas))
    
    /* work arrays size for ?levmar_blec_der and ?levmar_blec_dif functions.
     * should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes
     */
    #define LM_BLEC_DER_WORKSZ(npar, nmeas, nconstr) LM_LEC_DER_WORKSZ((npar), (nmeas)+(npar), (nconstr))
    #define LM_BLEC_DIF_WORKSZ(npar, nmeas, nconstr) LM_LEC_DIF_WORKSZ((npar), (nmeas)+(npar), (nconstr))
    
    /* work arrays size for ?levmar_bleic_der and ?levmar_bleic_dif functions.
     * should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes
     */
    #define LM_BLEIC_DER_WORKSZ(npar, nmeas, nconstr1, nconstr2) LM_BLEC_DER_WORKSZ((npar)+(nconstr2), (nmeas)+(nconstr2), (nconstr1)+(nconstr2))
    #define LM_BLEIC_DIF_WORKSZ(npar, nmeas, nconstr1, nconstr2) LM_BLEC_DIF_WORKSZ((npar)+(nconstr2), (nmeas)+(nconstr2), (nconstr1)+(nconstr2))
    
    #define LM_OPTS_SZ    	 5 /* max(4, 5) */
    #define LM_INFO_SZ    	 10
    #define LM_ERROR         -1
    #define LM_INIT_MU    	 1E-03
    #define LM_STOP_THRESH	 1E-17
    #define LM_DIFF_DELTA    1E-06
    #define LM_VERSION       "2.5 (December 2009)"
    
    #ifdef LM_DBL_PREC
    /* double precision LM, with & without Jacobian */
    /* unconstrained minimization */
    extern int dlevmar_der(
          void (*func)(double *p, double *hx, int m, int n, void *adata),
          void (*jacf)(double *p, double *j, int m, int n, void *adata),
          double *p, double *x, int m, int n, int itmax, double *opts,
          double *info, double *work, double *covar, void *adata);
    
    extern int dlevmar_dif(
          void (*func)(double *p, double *hx, int m, int n, void *adata),
          double *p, double *x, int m, int n, int itmax, double *opts,
          double *info, double *work, double *covar, void *adata);
    
    /* box-constrained minimization */
    extern int dlevmar_bc_der(
           void (*func)(double *p, double *hx, int m, int n, void *adata),
           void (*jacf)(double *p, double *j, int m, int n, void *adata),  
           double *p, double *x, int m, int n, double *lb, double *ub,
           int itmax, double *opts, double *info, double *work, double *covar, void *adata);
    }
    

    Der Aufruf, welcher den Fehler verursacht, sieht wie folgt aus:

    int ret =  dlevmar_bc_der(&FunctionToFit, &FuntionsJacobian, p, x, m, n, lb, ub, itMax, NULL, info, NULL, NULL, NULL);
    

    Ich hatte schon mal ein ähnliches Problem mit diesem Aufruf (http://www.c-plusplus.net/forum/173233), da war aber das __clrcall nicht dabei und ich habe es auch lösen können. Jetzt klappt es aber nicht mehr 😞 Hoffe ihr könnt mir irgendwie helfen.
    Besten Gruß,
    physici



  • Vielleicht hilft es das hier zu verwenden:
    http://msdn.microsoft.com/en-us/library/0adb9zxe(v=vs.80).aspx



  • FunctionToFit ist __clrcall; also z.B. eine Member-Funktion einer .NET Klasse... das geht nicht; da bringt Dir auch die Compiler-Einstellung (__cdecl) nix...
    Mach eine reine "C-Funktion" und es geht. Darin kannst Du ja dann die Klassen-methode aufrufen...



  • FunctionToFit ist __clrcall; also z.B. eine Member-Funktion einer .NET Klasse...

    Jupp, diese Funktion steckt in der gleichen Klasse, wie die andere Funktion welche den genannten Aufruf enthält.

    Mach eine reine "C-Funktion" und es geht.

    Meinst du, dass ich die Funktion "FunctionToFit" aus der Klasse rausnehme und diese dann "allein" steht?

    Also etwa so:

    void FunctionToFit(...){}
    
    class Mathematics
    {
    public: void DoLevenberg(...)
    {
    int ret =  dlevmar_bc_der(...);
    }
    }
    


  • Du kannst sie auch static machen.

    Wenn es eine Member Funktion ist, dass ist auch für natice C das __cdecl falsch; da eine Member Funktion mit __thiscall übersetzt wird... Somit ist dies kein .NET spezifisches Problem was Du hast...

    Markiere sie "static", dann sollte es gehen...
    😉



  • Ich werd es mal ausprobieren, wenn ich die Bibliothek wieder zum Laufen bekomme. Momentan mag fabriziert er eine Reihe weiterer Linker-Fehler, die aber mit der Bibliothek selbst zu tun haben.

    Gibt es irgendwo einen Überblick über die verschiedenen Aufrufkonventionen?
    Das scheint mir ja ein tieferes Verständnis von C voraus zu setzen, dass ich leider nicht mitbringe. Benutze C eigentlich nur, weil es die speziellen Mathebibliotheken nur als reines C gibt und somit nicht in C# laufen (hab ich zumindest irgendwo mal gelesen).


Anmelden zum Antworten