在基于 Qt 的库中选择性导出类成员
为了优化基于 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 环境中出现的之外,它还可能发生在使用宏扩展来生成声明的任何地方,如本例所示。
In an effort to optimize the binary of a Qt-based dynamic library, I'm attempting to selectively export a number of relevant methods from classes that inherit from QObject
and use moc
to define custom signals and slots, instead of exporting them entirely (all of their members). Some sample code is below.
#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();
};
The idea: since h()
and i()
are private (and no inline method call any of these functions), there is no need to export these symbols, since they will be used by the library alone. On the other hand, f()
and g()
are members eligible for exporting, so they're explicitly marked for that.
The problem: the Q_OBJECT
macro declares a couple of virtual method overrides for methods in QObject
, and these methods are not exported (since the macro will expand to declarations not containing LIB_SHARED
or Q_DECL_EXPORT
). Thus, the virtual table will be incomplete in client code.
The (un)solution: apply LIB_SHARED
to the entire class, as it is typically suggested:
class LIB_SHARED C: public QObject { /* ... */ };
This solves linking problems, but the primary goal (eliminating unnecessary export table entries) is not reached, at least not for QObject
-based classes.
The question: is there any way to achieve the desired result? I've tried messing a bit around the Q_OBJECT
macro, with no success.
I hope for a solution that works on Linux systems too (assuming hidden symbol visibility as default), so .def
files are not applicable. Hacks, however, are welcome :)
Any help is appreciated.
PS: Note that besides this problem is framed in a Qt environment, it can happen anywhere where a macro expansion is used to generate declarations, as in this case.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试使用 pimpl idiom 并仅导出公共部分。例如:
并创建私有类,放置所有私有(不可导出)内容:
然后从公共类初始化并调用私有实现。
Try to use pimpl idiom and export only public part. For example:
And create private class where placed all private (non exportable) stuff:
Then initialize and call private implementation from public class.