Impossible de dépasser “la référence indéfinie à« XXXX »»

J’écris actuellement une bibliothèque de wrapper avec en-tête uniquement, censée fournir un access C ++ à du code FORTRAN. Mais je suis coincé à la ‘référence indéfinie (…)’

Je dois dire que je suis un peu surpris, car j’ai compilé mes propres fonctions en C ++ en utilisant cette routine FORTRAN, sans aucun problème.

Peut-être quelques mots sur la structure. La bibliothèque suit le modèle de singleton, mais sans possibilité d’instancier la bibliothèque par l’utilisateur. Ainsi, le seul point d’entrée pour l’utilisateur est une méthode statique MultiNestWrapper::Wrapper::run() . MultiNestWrapper est un espace de noms, Wrapper est une classe MultiNestWrapper modèles (afin que vous puissiez désormais déterminer dans quelle mesure le type de calcul à utiliser affecte les résultats et les performances). La routine FORTRAN est déclarée en dehors de cet espace de noms, comme

 extern "C" { extern void __nested_MOD_nestrun(int *, int *, int *, double *, double *, int *, int *, int *, int *, int *, double *, const char *, int *, int *, int *, int *, void (*Loglike)(double *, int *, int *, double *), void (*dumper)(int *, int *, int *, double **, double **, double *, double *, double *), int *context); } 

et je l’appelle comme

 __nested_MOD_nestrun(&_mmodal, &_ceff, &_nlive, &_tol, &_efr, &_ndims, &_nPar, &_nClsPar, &_maxModes, &_updInt, &_Ztol, _root, &_seed, _pWrap, &_fb, &_resume, internalLogLike, internalDumper, &_context); 

Et les types d’arguments correspondent.

Lorsque j’essaie de le comstackr, j’obtiens le message d’erreur suivant:

 [dare2be@schroedinger multinest-interfejs]$ make all g++ -c ExampleLibMnCpp.cpp -o ExampleLibMnCpp.o gfortran -lstdc++ -llapack -lblas -lnest3 -L/usr/local/lib ExampleLibMnCpp.o -o ExampleLibMnCpp ExampleLibMnCpp.o: In function `MultiNestWrapper::Wrapper::run(MultiNestWrapper::MNParams*, double (*)(double const*, int), bool, std::basic_ssortingng<char, std::char_traits, std::allocator >, int, double, int, double, void (*)(int*, int*, int*, double**, double**, double*, double*, double*), int, double, bool)': ExampleLibMnCpp.cpp:(.text._ZN16MultiNestWrapper7WrapperIdE3runEPNS_8MNParamsIdEEPFdPKdiEbSsididPFvPiS9_S9_PPdSB_SA_SA_SA_Eidb[MultiNestWrapper::Wrapper::run(MultiNestWrapper::MNParams*, double (*)(double const*, int), bool, std::basic_ssortingng<char, std::char_traits, std::allocator >, int, double, int, double, void (*)(int*, int*, int*, double**, double**, double*, double*, double*), int, double, bool)]+0x585): undefined reference to `__nested_MOD_nestrun' collect2: ld returned 1 exit status make: *** [ExampleLibMnCpp] Error 1 

Mais, notez que

 [dare2be@schroedinger multinest-interfejs]$ nm /usr/local/lib/libnest3.a | grep __nested_MOD_nestrun 000000000001e0f0 T __nested_MOD_nestrun 

J’ai toujours traité moi-même de ces références non définies. Mais maintenant, je ne peux pas comprendre cela. Je précise -lnest3 -L/usr/local/lib explicite et /usr/local/lib/libnest3.a contient la routine sur laquelle l’éditeur de liens se plaint … Aidez un frère! 🙂

EDIT: fautes de frappe fixes

L’ordre dans lequel vous spécifiez les bibliothèques dans la ligne de commande de GCC est important. Lisez les pages de manuel GCC pour plus de détails. En bref, vous devez spécifier les bibliothèques ( -lnest3 etc.) après les modules qui les utilisent. (Je spécifie toujours les bibliothèques à la fin de la ligne de commande.)

Dans votre cas, vous devez écrire

 gfortran ExampleLibMnCpp.o -o ExampleLibMnCpp -L/usr/local/lib -lstdc++ -llapack -lblas -lnest3 

Peut-être devrez-vous spécifier les fichiers source avant les bibliothèques lorsque vous lierez tout. Comme ça:

 gfortran *.o -lblas -l... ... 

Les linkers sont parfois difficiles quant à l’ordre de leurs arguments.