无法通过“未定义的对‘XXXX’的引用";

2022-01-11 00:00:00 fortran linker c++

我目前正在编写一个仅包含标头的包装库,它应该提供对某些 FORTRAN 代码的 C++ 访问.但我被困在'未定义的参考(...)'

I'm currently writing a header-only wrapper library which is supposed to provide C++ access to some FORTRAN code. But I'm stuck at the 'undefined reference (...)'

我必须说我有点惊讶,因为我使用这个 FORTRAN 例程在 C++ 中编译了自己的函数,完全没有问题.

I must say I'm a little bit surprised because I compiled my own functions in C++ using this FORTRAN routine, with no problems at all.

也许是关于结构的几句话.该库遵循单例模式,但无法由用户实例化该库.所以用户的唯一入口点是一个静态方法MultiNestWrapper::Wrapper::run().MultiNestWrapper 是一个命名空间,Wrapper 是一个模板类(以便将来您可以基准测试选择执行计算的类型如何影响结果和性能).FORTRAN 例程在此命名空间之外声明,如

Maybe a few words about the structure. The library follows the singleton pattern, but without the possibility of instantiating the Library by the user. So the only entry point for the user is a static method MultiNestWrapper::Wrapper<T>::run(). MultiNestWrapper is a namespace, Wrapper<T> is a templated class (so that in future you can benchmark how choosing on which type to perform calculations affects results and performance). The FORTRAN routine is declared outside of this namespace, as

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

并且参数的类型匹配.

当我尝试编译它时,我收到以下错误:

When I try to compile it, I get the following error:

[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 包含链接器的例程抱怨...请帮助兄弟!:)

I've always dealt with those undefined references myself. But now I can't wrap my head around this. I specify -lnest3 -L/usr/local/lib explicite and /usr/local/lib/libnest3.a contains the routine the linker whines about... Please, help a brother out! :)

修正错别字

推荐答案

在 GCC 命令行中指定库的顺序很重要.阅读 GCC 手册页了解详细信息 - 简而言之,您必须指定库(-lnest3 等)after 使用它们的模块.(我总是在命令行末尾指定库.)

The order in which you specify libraries in GCC's command-line matters. Read GCC man pages for details - in short you have to specify libraries (-lnest3 etc) after modules that use them. (I always specify libraries in the end of the command-line.)

在你的情况下,你必须写

In your case you have to write

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

相关文章