为什么在头文件中定义的C ++虚函数不能在vtable中编译和链接? [英] Why C++ virtual function defined in header may not be compiled and linked in vtable?

查看:297
本文介绍了为什么在头文件中定义的C ++虚函数不能在vtable中编译和链接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况如下。我有共享库,其中包含类定义 -

Situation is following. I have shared library, which contains class definition -

QueueClass : IClassInterface
{
   virtual void LOL() { do some magic}
}

我的共享库初始化类成员

My shared library initialize class member

QueueClass *globalMember = new QueueClass();

我的共享库导出C函数,返回指向globalMember的指针 -

My share library export C function which returns pointer to globalMember -

void * getGlobalMember(void) { return globalMember;}

我的应用程序使用像这样的globalMember

My application uses globalMember like this

((IClassInterface*)getGlobalMember())->LOL();

现在非常糟糕的东西 - 如果我不从共享库引用LOL,那么LOL没有链接并从应用程序中调用它引发异常。原因 - VTABLE包含nul代替指向LOL()函数的指针。

Now the very uber stuff - if i do not reference LOL from shared library, then LOL is not linked in and calling it from application raises exception. Reason - VTABLE contains nul in place of pointer to LOL() function.

当我将LOL()定义从.h文件移动到.cpp时,突然出现在VTABLE中,一切正常。
什么解释了这个行为? (gcc编译器+ ARM架构_)

When i move LOL() definition from .h file to .cpp, suddenly it appears in VTABLE and everything works just great. What explains this behavior?! (gcc compiler + ARM architecture_)

推荐答案

链接器是这里的罪魁祸首。当函数是内联函数时,它有多个定义,在每个cpp文件中引用它。如果你的代码永远不引用函数,它从不会生成。

The linker is the culprit here. When a function is inline it has multiple definitions, one in each cpp file where it is referenced. If your code never references the function it is never generated.

但是, vtable 布局是在编译时确定的与类定义。编译器可以很容易地知道 LOL()是一个虚函数,需要在 vtable 中有一个条目。

However, the vtable layout is determined at compile time with the class definition. The compiler can easily tell that the LOL() is a virtual function and needs to have an entry in the vtable.

当它获取应用程序的链接时间时,会尝试填充 QueueClass :: _ VTABLE 但是没有找到 LOL()的定义并留空(null)。

When it gets to link time for the app it tries to fill in all the values of the QueueClass::_VTABLE but doesn't find a definition of LOL() and leaves it blank(null).

是在共享库中的文件中引用 LOL()。简单的例如& QueueClass :: LOL; 。您可能需要将它分配给一个抛出的变量,以使编译器停止抱怨没有效果的语句。

The solution is to reference LOL() in a file in the shared library. Something as simple as &QueueClass::LOL;. You may need to assign it to a throw away variable to get the compiler to stop complaining about statements with no effect.

这篇关于为什么在头文件中定义的C ++虚函数不能在vtable中编译和链接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆