我有 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 ();
}
这是使用 gcc
使用 CMake
构建的:
ADD_LIBRARY (plugin_implementation SHARED PluginImplementation.cpp)
这构建了 libplugin_implementation.so
,即使 PluginImplementation::bar
没有实现。
我知道缺少的符号可能在运行时在程序的其他地方定义,因此链接器允许它从动态库中丢失。
我不想那样。
有没有办法让 .so
无法构建,除非定义了所有 class 成员?
最佳答案
如果您的目标是现代 ELF,并且您不希望通过名称或其他符号直接引用此类,则可以将可见性设置为隐藏:
class __attribute__ ((visibility ("hidden")))
PluginImplementation : public PluginBase
然后链接器将尝试在本地(在共享对象内)解析实现虚拟方法的函数的符号,这将导致硬链接(hard link)器错误(为便于阅读而包装):
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
即使您省略了控制 vtable 发射的成员函数(以便共享对象不包含 vtable 及其函数指针),new_instance
函数调用的构造函数具有存储 vtable 指针,并且在隐藏可见性的情况下,这也会产生 undefined symbol 错误。
关于c++ - 如果一个类没有完全实现,我可以强制共享 C++ 库无法构建吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54636278/