Экспортируется ли конструктор класса из общей библиотеки? - PullRequest
1 голос
/ 23 сентября 2010

У меня есть общая библиотека lib.so, содержащая класс Foo.Я загружаю динамически (с dlopen в UNIX) lib.so.После загрузки я хочу создать экземпляр Foo.
Могу ли я просто использовать оператор new для создания объекта Foo, или мне нужно будет создать экспортированный фабричный метод, помещенный в lib.so, который будетсоздать этот объект для меня?

На самом деле вопрос заключается в том, экспортируется ли конструктор Foo и можно ли его просто вызвать с помощью оператора new.Я думаю, что все классы и методы в общей библиотеке в UNIX по умолчанию экспортируются, и мне не нужно экспортировать их явно, как в Windows DLL.

Помимо сокрытия способа создания (и, возможно, инициализации) объекта Foo, есть ли другие причины для использования метода фабрики при создании объекта класса, содержащегося в разделяемой библиотеке?

Ответы [ 2 ]

0 голосов
/ 23 сентября 2010

Основной ответ - да. Однако дьявол кроется в деталях. В Windows с использованием компилятора Microsoft C ++ ВСЕ символы, будь то методы, переменные и т. Д., Не экспортируются по умолчанию для DLL. Вам необходимо явно экспортировать функции, классы и / или глобальные переменные. Я полагаю, что это также относится и к компилятору Borlands (я могу ошибаться).

В случае с GCC раньше все экспортировалось по умолчанию, и вы не могли его контролировать. По состоянию на пару лет назад это изменилось с добавленным атрибутом (я не могу точно вспомнить, как он назывался, но он работал аналогично Microsoft __declspec (dllexport)).

Таким образом, если вы определите класс и пометите его как экспортированный (как бы вы ни выбрали), у него будет экспортирован его конструктор. Однако, как упоминалось в предыдущем постере, из-за природы C ++ имя символа меняется в зависимости от того, какой компилятор вы используете, а также, иногда, от какой версии компилятора C ++. Это не обязательно проблема, это зависит от того, как вы хотите использовать вещи, но это означает, что вы должны знать об этом.

0 голосов
/ 23 сентября 2010

Есть проблемы с этим подходом.В частности, при использовании разных версий одного и того же компилятора для библиотеки и программы вы не гарантируете, что функции-члены класса имеют одно и то же имя символа.

Поэтому используйте заводскую настройку.подход и непрозрачные типы указателей C:

// .cpp file
class Foo { ... };

// .h file
struct FooHandle;

#ifdef __cplusplus
extern "C"
{
    FooHandle* constructFoo(...);
    void releaseFoo(FooHandle*);
    int someFooMethod(FooHandle*, int param1, ...);
}
#endif

Всегда используйте функции C и непрозрачные типы указателей при экспорте общих библиотек.

...