Qt 对象的 staticMetaObject 地址在可执行文件中与链接的 dll 不同

问题描述 投票:0回答:1

我遇到的问题是,从主可执行文件的代码读取的 QObject

staticMetaObject
的地址与从使用
QPluginLoader
加载的 dll 读取时的地址不同。有问题的类属于加载的 DLL。由于不同的原因,DLL 也在构建时被链接。此问题导致
qobject_cast
失败,因为我给出的模板参数的
staticMetaObject
metaObject()
方法返回的不同,并且元对象系统会比较元对象的地址以检查继承。

令人困惑的是,这似乎只发生在 Windows 上,而且只有当我使用 CMake 而不是 QMake 时才会发生。

这一定是我的构建指令,但我对库链接了解不够。我认为这是因为运行时加载的 DLL 内的静态变量当然会有不同的地址,但我不明白为什么我的项目的 QMake 版本不会发生这种情况。

感觉像是符号可见性/导出问题。

我尝试设置

WINDOWS_EXPORT_ALL_SYMBOLS
或仅将
-Wl,--export-all-symbols
添加到所有目标,但没有任何改变。该库使用
target_link_libraries(exe PRIVATE dll)
进行链接,其中
dll
是相关库。

c++ qt cmake linker dllexport
1个回答
0
投票

似乎是用户错误。为了直接从构建目录运行,Qt Creator 提供了将构建库路径添加到运行环境的功能,但对于 CMake 来说效果不佳,因此我必须添加 CMake 指令以将 DLL 复制到可执行文件的文件夹中。插件加载程序引用构建目录中

lib
子文件夹内的 DLL,但作为可执行文件启动的一部分打开的 DLL 是同一目录中的 DLL。

两个相同的 DLL,但位置不同。我的猜测是,由于可执行目录中的目录已经被可执行文件打开,因此使用插件加载器再次打开它会重用事物的地址,但如果使用不同的路径打开,则它是不同的地址空间。

我没有看到我们的插件加载器在可执行目录之外搜索,所以我修复了这个问题,现在它可以工作了。

© www.soinside.com 2019 - 2024. All rights reserved.