如果类未完全实现,是否可以强制共享C++库无法生成?

Can I force a shared C++ library to fail to build if a class isn't fully implemented?

本文关键字:C++ 共享 实现 是否 如果      更新时间:2023-10-16

我有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)

即使未实现PluginImplementation::bar,也会生成libplugin_implementation.so

我知道缺少的符号可能在运行时在程序的其他地方定义,因此链接器允许它在动态库中丢失。

我不想这样。

有没有办法使.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

即使省略了控制 vtable 发射的成员函数(以便共享对象不包含 vtable 及其函数指针(,new_instance函数也会调用一个构造函数,该构造函数必须存储 vtable 指针,并且在隐藏可见性的情况下,这将产生未定义的符号错误, 太。

我认为您必须创建一个测试或其他一些代码段,该代码具有main,链接到共享库,并尝试实例化有问题的类。无论如何,这似乎是一个好主意,因为您应该进行单元测试。