В попытке оптимизировать двоичный файл динамической библиотеки на основе Qt я пытаюсь выборочно экспортировать ряд соответствующих методов из классов, которые наследуются от QObject
и используйте moc
для определения пользовательских сигналов и слотов, вместо того, чтобы экспортировать их полностью (все их элементы).Ниже приведен пример кода.
#ifdef LIB_BUILD
#define LIB_SHARED Q_DECL_EXPORT
#else
#define LIB_SHARED Q_DECL_IMPORT
#endif
class C: public QObject {
Q_OBJECT
public:
LIB_SHARED void f();
/* ... */
public slots:
LIB_SHARED void g();
private:
void h();
private slots:
void i();
};
Идея: , поскольку h()
и i()
являются частными (и никакой встроенный метод не вызывает ни одну из этих функций), в этом нет необходимости.экспортировать эти символы, так как они будут использоваться только библиотекой.С другой стороны, f()
и g()
являются членами, имеющими право на экспорт, поэтому они явно помечены для этого.
Проблема: макрос Q_OBJECT
объявляет парувиртуального метода переопределяет методы в QObject
, и эти методы не экспортируются (поскольку макрос будет расширяться до объявлений, не содержащих LIB_SHARED
или Q_DECL_EXPORT
).Таким образом, виртуальная таблица будет неполной в клиентском коде.
(не) решение: применить LIB_SHARED
ко всему классу, как обычно предлагается:
class LIB_SHARED C: public QObject { /* ... */ };
Это решает проблемы связывания, но основная цель (исключение ненужных записей таблицы экспорта) не достигнута, по крайней мере, для классов QObject
.
Вопрос: Есть ли способ достичь желаемого результата?Я попытался немного поработать с макросом Q_OBJECT
, но безуспешно.
Я надеюсь, что решение будет работать и в системах Linux (при условии, что по умолчанию видимость скрытых символов), поэтому файлы .def
непригодный.Хаки, тем не менее, приветствуются:)
Любая помощь приветствуется.
PS: Обратите внимание, что помимо этой проблемы, созданной в среде Qt, она может происходить везде, где используется расширение макроса длягенерировать объявления, как в этом случае.