Могу ли я заставить библиотеку C ++ не создавать, если класс не полностью реализован? - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть плагины 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 завершиться неудачно, если не определены все члены class ?

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Если ваша цель - современный 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, а в случае скрытой видимости это будетвыдает также неопределенную символьную ошибку.

0 голосов
/ 11 февраля 2019

Я бы подумал, что вам придется создать тест или какой-то другой фрагмент кода, который имеет main, ссылки на общую библиотеку и пытается создать экземпляр рассматриваемого класса.Похоже, в любом случае это было бы хорошей идеей, потому что вы должны проходить модульное тестирование.

...