Когда у меня есть абстрактный базовый класс 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()
в исполняемом файле, чтобы он мог быть решен во время выполнения? «
Поскольку метод bar определен как виртуальный, нет необходимости в статическом связывании. Связывание будет выполняться динамически во время выполнения в зависимости от типа объекта, на который ссылается * my_foo. Независимо от того, определено ли оно в libX.a или libY.a.
Ответьте на вопрос, как заставить компоновщик связать символ, ссылающийся на foo_impl :: bar ()?
Вы не можете заставить компоновщик ссылаться на конкретную реализацию. Связывание будет происходить в зависимости от того, какой адрес объекта вы получили от receive_a_foo_from_somewhere ().
Очевидно, что реализация должна быть связана с вашим exe. Если это не доступно, это определенно потерпит неудачу. Но вы не можете заставить компоновщик связать конкретную реализацию,
Кажется, есть по крайней мере два способа заставить компоновщик включать foo_impl::bar()
функциональность в исполняемом файле:
-Wl,--whole-archive
связать всю статическую библиотеку — несмотря ни на что.foo_impl
используется в программе, ее виртуальные функции помечены как использованные и, следовательно, включены в исполняемый файл. Это также может быть бесполезной статической фиктивный foo_impl
объект.