微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 对vtable的未定义引用 – 虚拟成员,由gsoap生成的类

gsoap及其工具wsdl2h和soapcpp2为我提供了一个包含以下内容的soapStub.h文件
class SOAP_CMAC ns2__SOAPKunden
{
  public:
    std::string *adresszusatz; 
    // ...
  public:
    virtual int soap_type() const { return 7; }
    // ...
    ns2__SOAPKunden() : adresszusatz(NULL),x(NULL) { }   // left out all member init.
    virtual ~ns2__SOAPKunden() { }
};

我从一个小应用程序开始,使用该类用informix DB中的数据填充对象.

但要成功编译我必须放弃所有的虚拟东西 – 我发现很多关于这个错误的帖子和在子类中使用虚拟成员 – 否则我得到

main.o: In function `ns2__SOAPKunden::ns2__SOAPKunden()':
main.cpp:(.text._ZN15ns2__SOAPKundenC1Ev[ns2__SOAPKunden::ns2__SOAPKunden()]+0xf): undefined reference to `vtable for ns2__SOAPKunden'
main.o: In function `ns2__SOAPKunden::~ns2__SOAPKunden()':
main.cpp:(.text._ZN15ns2__SOAPKundenD1Ev[ns2__SOAPKunden::~ns2__SOAPKunden()]+0x13): undefined reference to `vtable for ns2__SOAPKunden'
collect2: ld returned 1 exit status

我承认经过多年的脚本编写后,我很难理解C代码……我想问一下下一步要做什么的建议.我的班级没有派生类,例如让我惊讶的是什么.

解决方法

错误意味着虚拟表未在最终二进制文件(可执行文件或库)中正确编译/链接.导致此错误的常见情况有两种:

>您没有链接包含虚拟表定义的目标文件–i.e.您将soapStub.cpp编译为soapStub.o,但未将该二进制文件添加链接器命令行.
>编译器不会在任何地方生成虚拟表,因此即使您包含所有目标文件,也不包括虚拟表.

对于没有经验的开发人员来说,第二种情况最难识别,并且可能是由标题中定义的类包含虚函数引起的.如果所有虚函数都是内联定义的,编译器将在包含头的所有转换单元中生成虚拟表,并将其标记为弱符号,以便链接器可以丢弃它们,但如果稍后添加新的虚方法,如果从其中一个函数删除定义,则在标题中保留未定义 – 然后编译器不会在每个转换单元中生成虚拟表,而只在定义这些函数的虚拟表中生成虚拟表.

要检查的事项:

>您正在链接所有目标文件>要么所有虚函数都在类定义中内联定义,要么你有一个定义虚函数的.cpp,你要将其链接到.

原文地址:https://www.jb51.cc/c/115123.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐