C++链接时出现未定义引用错误

4

我想知道是否有人能够帮助我,因为我已经在这个问题上纠结了两天。

我已经完成了编译,在Linux上尝试链接源代码时出现了“未定义的引用”错误。

使用以下命令进行编译:

g++ -g -I/u01/kasunt/workspace/corelibCORBA/include -I/u01/kasunt/workspace/corelibCORBA/installed_components/include -I/u01/kasunt/workspace/corelibCORBA/idl -I/u01/kasunt/workspace/corelibCORBA/src/Server -I/u01/kasunt/workspace/corelibCORBA/installed_components/idl -I/u01/kasunt/workspace/corelibCORBA/installed_components/src/Server -I/u01/kasunt/workspace/corelibCORBA/installed_components/imake -DNARROWPROTO -I . -I/u01/kasunt/workspace/corelibCORBA/installed_components/include -W -Wall -Wpointer-arith -pipe -D_POSIX_THREADS -D_POSIX_THREAD_SAFE_FUNCTIONS -g -O -I/u01/kasunt/workspace/corelibCORBA/include -g -O -I/u01/kasunt/workspace/corelibCORBA/include -fvisibility=hidden -fvisibility-inlines-hidden -DACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS=1 -W -Wall -Wpointer-arith -ggdb -pipe -Wall -g -D__linux__ -D__x86__ -rdynamic -D_REENTRANT -DTAO_HAS_INTERCEPTORS=0 -DTAO_HAS_VALUETYPE=1 -D_REENTRANT -DACE_HAS_AIO_CALLS -D_GNU_SOURCE -I/usr/local/ACE+TAO+CIAO-5.7.9/ACE_wrappers -I/usr/local/ACE+TAO+CIAO-5.7.9/ACE_wrappers/TAO -I/usr/local/ACE+TAO+CIAO-5.7.9/ACE_wrappers/TAO/orbsvcs -DACE_HAS_EXCEPTIONS -D__ACE_INLINE__ -c -o TestSeqWrapper.o TestSeqWrapper.cpp

使用以下命令进行链接:

g++ -o TestSeqWrapper TestSeqWrapper.o -g -L/u01/kasunt/workspace/corelibCORBA/lib -L/u01/kasunt/workspace/corelibCORBA/installed_components/lib -g -O -Wl,-E -L/usr/local/ACE+TAO+CIAO-5.7.9/ACE_wrappers/lib -L/usr/local/ACE+TAO+CIAO-5.7.9/ACE_wrappers/lib -L/usr/local/ACE+TAO+CIAO-5.7.9/ACE_wrappers/TAO/tao -L/u01/kasunt/workspace/corelibCORBA/installed_components/idl -lcorelibCORBA -lcorelibCORBA /u01/kasunt/workspace/corelibCORBA/installed_components/lib/corelibCORBA3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/CorbaController3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/EConcurrency3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/corelibLogger3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/LeakTracker3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/trace3r.lib -lDefineTimeZone /u01/kasunt/workspace/corelibCORBA/installed_components/lib/timestamp3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/ApplConfig3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/appl3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/logstream3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/disklog3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/timeout3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/getpnam3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/config3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/strl3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/string3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/command3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/cmdargs3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/CppUtils3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/BuildTag3r.lib /u01/kasunt/workspace/corelibCORBA/installed_components/lib/exception3r.lib -lCorbaIdl -lTAO_Valuetype -lTAO_PortableServer -lTAO_IORTable -lTAO_AnyTypeCode -lTAO_CosEvent -lTAO_CosNaming -lTAO -lACE
TestSeqWrapper.o: In function `SeqWrapper':
/u01/kasunt/workspace/corelibCORBA/include/corelibCORBA/SeqWrapper.hpp:165: undefined reference to `ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T()'

处理库的nm命令,我可以看到上述构造函数被包含在内。

nm --demangle ../installed_components/lib/libCorbaIdl.so | grep "ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T"
000327ba t ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T(ECONZ::Corba::ComboElementSeq_T const&)
000331c2 t ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T(unsigned int)
0002edb0 t ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T(unsigned int, unsigned int, ECONZ::Corba::ComboElement_T*, bool)
0002d768 t ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T()
00032e52 t ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T(ECONZ::Corba::ComboElementSeq_T const&)
0003172a t ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T(unsigned int)
0002d8e0 t ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T(unsigned int, unsigned int, ECONZ::Corba::ComboElement_T*, bool)
0002d8a6 t ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T()

源代码中有一行错误(第165行),SeqWrapper() : var_( new SequenceType ), size_( 0 ) { }

代码的一部分,

template< typename SEQUENCE >
class SeqWrapper : CppUtils::NonCopy
{
public:
   typedef SEQUENCE SequenceType;
   typedef typename SequenceType::_var_type SequenceType_var;

   typedef typename ElementTypeOf<SequenceType_var>::ElementType ElementType;
   typedef typename ElementTypeOf<SequenceType_var>::ReturnType ReturnType;
   typedef typename ElementTypeOf<SequenceType_var>::ConstReturnType ConstReturnType;

private:
   SequenceType_var var_;
   CORBA::ULong size_;

  void expand_( CORBA::ULong size )
  {
     // NOTE: current implementation assumes size only increases by small increments
     if (size > var_->length()) {
        var_->length( (size < 16)? 16 : (size > 256? size+256 : 2*size-2) );
     }
  }

public:
   SeqWrapper() : var_( new SequenceType ), size_( 0 ) { }
   SeqWrapper( CORBA::ULong reserve ) : var_( new SequenceType( reserve ) ), size_( 0 ) { var_->length( reserve ); }
   SeqWrapper( SequenceType *ownSeq ) : var_( ownSeq ), size_( ownSeq->length() ) { }

.....

TestSeqWrapper.cpp的源代码(我已经删除了大部分不必要的内容,以使其更少令人困惑)

#include <iostream>
#include <CppUtils/StringHelpers.hpp>
#include <corelibCORBA/SeqWrapper.hpp>
#include <CorbaC.h>

using namespace std;

int main()
{
    ECONZ::Corba::SeqWrapper< ECONZ::Corba::StringSeq_T > seq;
}

您可以看到,我已经在链接选项中指定了共享库(以粗体显示)。我最初认为这可能是某种依赖关系,将库标志移到开头,但没有影响。

感谢你的帮助。


1
你的路径设置不正确。检查你在Makefile中的LIBPATH和INCLUDEPATH设置。检查库所安装的路径是否正确,并指向所需的目录。 - DumbCoder
我刚刚粘贴了行号和代码的一部分。 - nixgadget
1
尝试将-lCorbaIdl移动到列表末尾。同时删除-g标志,我认为你在链接时不需要它。 - Dmitry Yudakov
如果你将 var_( new SequenceType ) 改为使用其他重载的构造函数,它是否仍然会出现未解决的引用? - greatwolf
@Dmitry Yudakov - 顺便说一下,感谢你去掉-g的提示。我不知道为什么之前没有发现它。但是这仍然无法解决问题:( - nixgadget
显示剩余10条评论
4个回答

1

既然你这么说

nm --demangle ../installed_components/lib/libCorbaIdl.so
> 0002d768 t ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T()

这意味着ComboElementSeq_T()在lib -lCorbaIdl中。
如果找不到引用,则表示它被此库之后指定的某个库使用:

> -lCorbaIdl -lTAO_Valuetype -lTAO_PortableServer -lTAO_IORTable
> -lTAO_AnyTypeCode -lTAO_CosEvent -lTAO_CosNaming -lTAO -lACE

因此,以下其中一个包含:TestSeqWrapper.o: In functionSeqWrapper'`

  • -lTAO_Valuetype
  • -lTAO_PortableServer
  • -lTAO_IORTable
  • -lTAO_AnyTypeCode
  • -lTAO_CosEvent
  • -lTAO_CosNaming
  • -lTAO
  • -lACE

请参见:GCC C++链接器错误:未定义对 'vtable for XXX' 的引用,未定义对 'ClassName :: ClassName()'的引用

如果将所有库构建为共享库,则此问题将消失。


我检查了所有这些库,只是为了确保。除了libCorbaIdl.so以外,它们都没有包含“ComboElementSeq_T”。 - nixgadget
第二个链接给出了完全相同的错误信息。也许它指向了一个缺失的库,但是这个错误信息与之前的相同,这告诉我它不依赖于其他库,对吧?而我链接的其他库都是来自ACE/TAO的现成库。而ECONZ::Corba中的“ComboElementSeq_T”是自定义编写的。 - nixgadget
@Martin,我有一个快速的问题,为什么gcc链接器是这样设计的?我看到来自不同工具链的其他链接器并不关心您指定它们的顺序,只要符号在某个地方存在即可。这对我来说似乎是一种不必要的实现细节。 - greatwolf
@Victor T:当链接静态库时,我遇到的所有链接器都是这样工作的。这是为了最小化应用程序的大小,使其仅包含实际运行所需的代码。 - Martin York
@Victor T. 这只会发生在静态链接库中(动态链接库完全不同)。移除所有的动态链接库,只使用静态链接库再试一次。 - Martin York
显示剩余6条评论

1

大家好,

经过喝了10杯咖啡和几个几乎失眠的夜晚,我终于找到了问题的根源。希望这能帮助到某些人,并且有人能够向我解释如何避免这种情况。以下是解决方法。

我再次使用-D选项运行了以下命令,这次它显示了完全不同的输出,而且我也有点预料到了。结果什么都没有,"ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T"未被找到。

nm -DC ../installed_components/lib/libCorbaIdl.so | grep "ECONZ::Corba::ComboElementSeq_T::ComboElementSeq_T"

然后,它让我认为是库的编译问题。因此,我仔细查看了编译器标志,并找到了这两个“-fvisibility = hidden -fvisibility-inlines-hidden”。 这来自于ACE / TAO,这是自GCC 4以来他们添加的新属性。 这会导致动态符号被隐藏。 所以,我想问任何知道此事的人,我应该如何链接库?

欲知更多请阅读http://gcc.gnu.org/wiki/Visibility


0

你的链接行有错别字吗?

-L/u01/kasunt/workspace/corelibCORBA/idl

应该是

-L/u01/kasunt/workspace/corelibCORBA/lib

libCorbaIdl位于/u01/kasunt/workspace/corelibCORBA/installed_components/lib中。 - nixgadget
那么连接器路径不是打错了吗?你可能想编辑你的问题并澄清一下。 - Sam Miller
“-L/u01/kasunt/workspace/corelibCORBA/lib -L/u01/kasunt/workspace/corelibCORBA/installed_components/lib”应该是它搜索的路径。 “-L/u01/kasunt/workspace/corelibCORBA/idl”不是一个错别字,而是一个空目录。我为了清晰起见将其删除了。谢谢。 - nixgadget

0

我不知道这是否对任何人有意义,但似乎将库作为静态而非共享使用完美地运行。因此,我附上了。

/u01/kasunt/workspace/corelibCORBA/installed_components/lib/libCorbaIdl.a

它完美地运行了。有人能解释一下吗?


可能是共享库的名称混淆问题,尽管我没有在任何地方使用外部代码。 - nixgadget

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接