我有C ++插件:
class PluginBase
{
public:
virtual void foo () = 0;
virtual void bar () = 0;
};
extern "C" PluginBase * new_instance ();
这被实现为共享库
class PluginImplementation : public PluginBase
{
void foo () override;
void bar () override;
}
void PluginImplementation::foo () {}
// void PluginImplementation::bar () {} // NOTE: MISSING
extern "C" PluginBase * new_instance ()
{
return new PluginImplementation ();
}
这是建立与CMake
使用gcc
:
ADD_LIBRARY (plugin_implementation SHARED PluginImplementation.cpp)
这将构建libplugin_implementation.so
即使PluginImplementation::bar
未实现。
我得到的是缺少符号可能会在运行时程序中其他地方定义,因此链接器允许它从一个动态库会丢失。
我不希望出现这种情况。
有没有一种方法,使.so
不能建立,除非所有的类成员的定义?
如果你的目标是现代ELF,你不要指望用它的名字或其他符号这一类的直接引用,您可以设置能见度为隐藏:
class __attribute__ ((visibility ("hidden")))
PluginImplementation : public PluginBase
则链接器将尝试解决用于实现本地虚拟方法(共享对象内)的功能的符号,而这将导致硬链接错误(为了便于阅读):
plugin.o:(.data.rel.ro.local._ZTV20PluginImplementation
[_ZTV20PluginImplementation]+0x18):
undefined reference to `PluginImplementation::bar()'
/usr/bin/ld: plugin.so: hidden symbol `_ZN20PluginImplementation3barEv'
isn't defined
即使你离开了,控制虚函数表(这样的共享对象不包含它的函数指针的虚函数表)的排放量的成员函数中,new_instance
函数调用具有存储虚表指针的构造,而在情况隐藏的知名度,这将产生一个未定义的符号错误,太。
我认为你必须创建一个测试或一些其他的代码具有main
,链接到共享库,并试图实例有关类别。这似乎是这将是一个好主意,因为反正你应该是单元测试。