виртуальные функции в статических библиотеках

Когда у меня есть абстрактный базовый класс foo, определенный в libX.a

class foo {
virtual void bar() = 0;
};

… и производный класс foo_impl, определенный в libY.a

class foo_impl : public foo {
void bar() { /* do something */ }
};

… и использовать обе библиотеки, чтобы связать программу -lX -lY

int main() {
foo* my_foo = receive_a_foo_from_somewhere();
my_foo->bar();
}

затем

  • как я могу заставить компоновщик на самом деле связать символ, ссылающийся на foo_impl::bar()?
  • делает objdump -t program список foo_impl::bar() когда это правильно связано?

РЕДАКТИРОВАТЬ: чтобы уточнить, я использую Linux с GCC или Clang

РЕДАКТИРОВАТЬ 2: пропустил virtual за bar()

РЕДАКТИРОВАТЬ 4: Я прошу прощения за отсутствующую ясность. Вопрос должен был быть «как я могу заставить компоновщик на самом деле включить foo_impl::bar() в исполняемом файле, чтобы он мог быть решен во время выполнения? «

0

Решение

Поскольку метод bar определен как виртуальный, нет необходимости в статическом связывании. Связывание будет выполняться динамически во время выполнения в зависимости от типа объекта, на который ссылается * my_foo. Независимо от того, определено ли оно в libX.a или libY.a.

Ответьте на вопрос, как заставить компоновщик связать символ, ссылающийся на foo_impl :: bar ()?

Вы не можете заставить компоновщик ссылаться на конкретную реализацию. Связывание будет происходить в зависимости от того, какой адрес объекта вы получили от receive_a_foo_from_somewhere ().

Очевидно, что реализация должна быть связана с вашим exe. Если это не доступно, это определенно потерпит неудачу. Но вы не можете заставить компоновщик связать конкретную реализацию,

0

Другие решения

Кажется, есть по крайней мере два способа заставить компоновщик включать foo_impl::bar() функциональность в исполняемом файле:

  1. С gcc можно использовать -Wl,--whole-archive связать всю статическую библиотеку — несмотря ни на что.
  2. Как отметил капитан Обвлиус, когда foo_impl используется в программе, ее виртуальные функции помечены как использованные и, следовательно, включены в исполняемый файл. Это также может быть бесполезной статической фиктивный foo_impl объект.
0

По вопросам рекламы [email protected]