为了优化基于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环境中构建的,它可能发生在使用宏扩展来生成声明的任何地方,就像在这种情况下一样。
答案 0 :(得分:2)
尝试使用pimpl习语并仅导出公共部分。例如:
class CPrivate;
class LIB_SHARED C: public QObject {
Q_OBJECT
private:
CPrivate* m_private;
public:
...
};
创建私有类,放置所有私有(不可导出)的东西:
class CPrivate : public QObject {
Q_OBJECT
public:
void h();
public slots:
void i();
}
然后从公共类初始化并调用私有实现。