2013-05-27 5 views
0

Когда у меня есть абстрактный базовый класс 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 programfoo_impl::bar() если он правильно связан?

EDIT: уточнить, я использую Linux с GCC или звоном

EDIT 2: пропустил virtual для bar()

EDIT 4: Я прошу прощения за отсутствие ясности. Вопрос должен был быть «как я могу заставить компоновщика фактически включить foo_impl::bar() в исполняемый файл, чтобы его можно было разрешить во время выполнения?»

+0

Как он узнает, куда его связать? это виртуальный метод, который требует динамического поиска. – Elazar

+0

Когда создается виртуальная таблица для 'foo_impl', функция-член' foo_impl' помечена как используемая, когда экземпляр объекта этого типа создается. Затем компоновщик автоматически включит его в ваше приложение. –

+0

EDIT 3: my_foo ** -> ** bar(); –

ответ

0

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

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

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

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

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

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

+0

... который должен завершиться неудачно, потому что компилятор (на самом деле компоновщик) никогда не включал символы libY.a – idefixs

+0

Ответ на вопрос, как заставить компоновщика связать символ, ссылающийся на foo_impl :: bar()? Вы не можете заставить компоновщик ссылаться на конкретную реализацию. Связывание будет происходить в зависимости от того, какой адрес объекта вы получили от receive_a_foo_from_somewhere(). Очевидно, что реализация должна быть связана с вашим exe. Если он недоступен, он определенно потерпит неудачу. Но вы не можете заставить линкер связывать конкретную реализацию, –

+0

извините, моя ошибка. см. EDIT 4 – idefixs

Смежные вопросы