Не может пройти мимо "неопределенной ссылки на" XXXX " - PullRequest
3 голосов
/ 12 августа 2011

В настоящее время я пишу библиотеку-оболочку только для заголовка, которая должна обеспечивать доступ C ++ к некоторому коду FORTRAN.Но я застрял в 'undefined reference (...)'

Должен сказать, что я немного удивлен, потому что я скомпилировал свои собственные функции в C ++, используя эту процедуру на FORTRAN, без каких-либо проблем..

Возможно, несколько слов о структуре.Библиотека следует шаблону синглтона, но без возможности создания экземпляра библиотеки пользователем.Таким образом, единственной точкой входа для пользователя является статический метод MultiNestWrapper::Wrapper<T>::run().MultiNestWrapper - это пространство имен, Wrapper<T> - шаблонный класс (так что в будущем вы сможете оценить, как выбор типа для выполнения вычислений влияет на результаты и производительность).Подпрограмма FORTRAN объявлена ​​вне этого пространства имен, как

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);
}

, и я называю это как

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

И типы аргументов совпадают.

Когда я пытаюсьчтобы скомпилировать его, я получаю следующую ошибку:

[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<double>::run(MultiNestWrapper::MNParams<double>*, double (*)(double const*, int), bool, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 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<double>::run(MultiNestWrapper::MNParams<double>*, double (*)(double const*, int), bool, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 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

Но учтите, что

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

Я всегда имел дело с этими неопределенными ссылками сам.Но теперь я не могу обернуть голову вокруг этого.Я указываю -lnest3 -L/usr/local/lib explicite и /usr/local/lib/libnest3.a содержит подпрограмму, о которой скулит линкер ... Пожалуйста, помогите брату!:)

РЕДАКТИРОВАТЬ: исправлены опечатки

Ответы [ 2 ]

5 голосов
/ 12 августа 2011

Порядок, в котором вы указываете библиотеки в командной строке GCC, имеет значение.Подробности смотрите в справочных страницах GCC - короче говоря, вы должны указать библиотеки (-lnest3 и т. Д.) после модулей, которые их используют.(Я всегда указываю библиотеки в конце командной строки.)

В вашем случае вы должны написать

gfortran ExampleLibMnCpp.o -o ExampleLibMnCpp -L/usr/local/lib -lstdc++ -llapack -lblas -lnest3
0 голосов
/ 12 августа 2011

Может быть, вам нужно указать исходные файлы перед библиотеками при связывании всего вместе.Например:

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

Линкеры иногда требовательны к порядку своих аргументов.

...