跨 dll 使用 QNetworkAccessManager
Posted
技术标签:
【中文标题】跨 dll 使用 QNetworkAccessManager【英文标题】:Using QNetworkAccessManager across dll 【发布时间】:2014-05-05 16:24:44 【问题描述】:我有一个 Qt5 应用程序,它使用 QNetworkAccessManager
进行网络请求,可通过单例访问,QPluginLoader
加载扩展程序,为程序添加功能。目前我正在为插件使用静态链接,一切正常。
但是,我想改用动态库来将核心功能与应用程序的其他部分分开。我已经通过宏添加了必要的declspec
,并在我的 .pro 文件中进行了必要的调整。
问题是,当从 dll 中使用 QNetworkAccessManager
时,经常(比如 4 次启动中的 3 次)只返回一个空请求或空指针。没有数据,没有错误字符串,没有标题。
这是我用来加载插件的代码:
template <typename PluginType>
static QList<PluginType*> loadModules()
QList<PluginType*> loadedModules;
foreach (QObject* instance, QPluginLoader::staticInstances())
PluginType* plugin = qobject_cast<PluginType*>(instance);
if (plugin)
loadedModules << plugin;
QDir modulesDir(qApp->applicationDirPath() + "/modules");
foreach (QString fileName, modulesDir.entryList(QDir::Files))
QPluginLoader loader(modulesDir.absoluteFilePath(fileName));
QObject *instance = loader.instance();
PluginType* plugin = qobject_cast<PluginType*>(instance);
if (plugin)
loadedModules << plugin;
return loadedModules;
在启动时调用的这个非静态非模板重载中使用的是:
bool AppController::loadModules()
m_window = new AppWindow();
/* some unimportant connection and splashscreen updating */
QList <ModuleInterface*> loadedModules = loadModules<ModuleInterface>();
foreach (ModuleInterface* module, loadedModules)
m_splash->showMessage(tr("Initializing module: %1").arg(module->getModuleName()),
Qt::AlignBottom | Qt::AlignRight, Qt::white);
module->preinit();
QApplication::processEvents();
// [1]
ControllerInterface *controller = module->getMainController();
m_window->addModule(module->getModuleName(),
QIcon(module->getIconPath()),
controller->primaryWidget(),
controller->settingsWidget());
m_moduleControllers << controller;
m_window->addGeneralSettings((new GeneralSettingsController(m_window))->settingsWidget());
m_window->enableSettings();
/* restoring window geometry & showing it */
return true;
但是,如果我将QThread::sleep(1);
插入标记为 1 的行中,它可以正常工作,但加载速度会变慢,我非常怀疑它是否是一个在任何地方都可以工作的稳定解决方案。
另外,我发送请求的站点是MyAnimeList。
【问题讨论】:
向我们展示如何使用 QNetworkAccessManager。我想你只是不等待它的回应。 @Bogdan 在应用程序的一部分中,我使用了一个使用QEventLoop
同步它的包装器。 (github.com/VeriTi/malstylerqt/blob/dll_heaven/base_app/…) 另一方面,我从QNetworkReply
异步解析一些XM。 (github.com/VeriTi/malstylerqt/blob/dll_heaven/mod_covers/blink/…)
您的来源对我来说似乎没问题。从 QNetworkAccessManager 获得 nullptr 是什么意思?如果你得到 QNetworkReplay==nullptr 那么恕我直言,这是一个 Qt 错误,你可以在没有数据但绝对没有 nullptr 的情况下进行重播(据我了解 Qt 文档)。
【参考方案1】:
好的,现在我终于调试好了。结果我在需要不同步访问的类之一中删除了内部 QNetworkAccessManager。那,更新到 Qt5.3 似乎解决了我的问题。
【讨论】:
以上是关于跨 dll 使用 QNetworkAccessManager的主要内容,如果未能解决你的问题,请参考以下文章