c++ - 如果一个类没有完全实现,我可以强制共享 C++ 库无法构建吗?

标签 c++ gcc dll cmake linker

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

相关文章:

c# - 从 C# 项目调用 c native 函数

c++ - 来自 NtCreateFile 的 STATUS_INVALID_PARAMETER

c++ - 在另一个成员函数中将成员函数指针作为参数发送

c++ - vector 构造函数中的函数匹配

c - 是否有 GCC 关键字允许结构重新排序?

python - 即使在编辑 PATH、在 distutils 中创建文件、删除所有 -mno-cygwin 实例后,也无法让 Cython 找到 MinGW gcc 编译器

c++ - 传入 pthread_creation 的参数

gcc - 设置自动工具以静态链接单个系统库

c++ - 如何消除 LoadLibrary() 函数中变量类型不兼容的错误?

.net - 如何找到特定 dll 的 PublicKeyToken?