【问题标题】:QNetworkAccessManager->get freezes when called in DLLQNetworkAccessManager->get 在 DLL 中调用时冻结
【发布时间】:2012-08-08 13:46:08
【问题描述】:

我有一个 dll,我想在其中进行一些网络连接,这个 dll 作为非托管 DLL 从 C# 应用程序中调用。 所有初始化工作正常,但每次 ->get() 应该运行时都会冻结。我有这个代码:

.........
QUrl path(remotePath);
QNetworkRequest request(path);

currentFile.setFileName(localPath);
if(!currentFile.open(QIODevice::WriteOnly)){
doCallback("failed to open: " + localPath);
}
doCallback("before get: " + remotePath);
QNetworkReply* reply = this->manager->get(request);
doCallback("after get: " + localPath);
...........

“获取前”回调执行得很好,但从来没有“获取后”回调,所以我猜当经理尝试 Get() 方法时它会完全冻结。我是否遗漏了什么,或者这只是通过 DLL 是不可能的?

【问题讨论】:

  • 如果不从非托管 DLL 调用相同的代码,是否可以工作?即编写一个小型 C++ 控制台应用程序并调用相同的代码,看看会发生什么。
  • 感谢您的快速回复。是的,我通过 Qt 创建了一个控制台应用程序,然后它工作正常......我想知道它是否与我没有在我的非托管 DLL 中运行任何 QApplication 而只是进行类调用有关......?跨度>
  • 好的,所以您没有创建本机控制台应用程序并调用了相同的代码。如果您在本机应用程序中调用的只是发布的代码并且遇到了同样的问题,那么您就知道问题所在了。
  • 好的,当然。所以我需要 QApplication 实例化和运行。但是我不想执行 QApplication,我怎样才能在 DLL 中执行此操作,你知道吗?
  • 您可能必须创建一个“初始化”函数,您可以从托管代码调用一次。 QT 实际上是一个 UI 框架,并不打算与另一个 UI 框架或平台一起使用。所以,你必须经历一些这样的过程才能让它在托管代码中正常工作。

标签: c# c++ qt dll qnetworkaccessmanager


【解决方案1】:

我的猜测是您的 QT 库是针对 opensll 构建的。 QNetworkAccessManager 查找 ssl dll、libeay32.dll 和 ssleay32.dll。 Win32 LoadLibrary 在尝试加载这些 dll 时会挂起整个进程、UI、信号槽等所有内容。将这些 dll 复制到可执行文件的目录中,加载将很快成功。

【讨论】:

    【解决方案2】:

    好吧,所以我得到了这个工作,我想我会分享我的知识。使用我的非托管 dll,我导出了一个创建新 QCoreApplication 的 init 函数,之后我可以通过使用 QCoreApplication 对象作为执行所有网络的类的父级来使用事件循环。

    QCoreApplication* coreApp = 0;
    extern "C" __declspec(dllexport) void initdll()
    {
        if (!coreApp) {
            int argc    = 0;
            coreApp = new QCoreApplication(argc, 0);
        }
        if(!MyFunc){
            MyFunc = new QtDll(coreApp);
        }
    }
    

    通过在我尝试任何网络之前在我的 C#(或其他)应用程序中调用这个 init 函数,我通过添加事件循环的 exec 使其与我第一篇文章中的代码一起工作。

    QNetworkReply* reply = this->manager->get(request);
    currentReply = reply;
    QEventLoop eLoop;
    connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
    eLoop.exec( QEventLoop::ExcludeUserInputEvents );
    

    感谢彼得的反馈。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      • 2011-08-03
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多