c++ - 在插件(DLL)中使用 Qt 网络模块?

标签 c++ windows qt

我正在为大型非 Qt Windows 应用程序 ( Autodesk 3ds Max ) 编写插件。该插件是用 C++11 编写的 native DLL。

我希望我的插件通过使用 Qt 4.8.7 网络组件查询 GitHub 的 HTTP API 来检查更新。

我尝试了一个简单的测试,但是 QNetworkAccessManager::get() 调用永远挂起:

QNetworkAccessManager* manager = new QNetworkAccessManager(this);
QNetworkReply* reply = manager->get(QNetworkRequest(QUrl("https://api.github.com/repos/appleseedhq/appleseed-max/releases")));
QByteArray result = reply->readAll();

我想这是因为我没有运行 Qt 事件循环。

在这里进行的正确方法是什么?我需要一个 QtApplication 吗?鉴于我正在编写一个插件而不是一个应用程序,我应该如何构建东西?

最佳答案

解决它的方法是从 DLL 导出函数启动新的 QThread 派生对象并在其中运行事件线程:

    // Mind the files. For MOC compiler to create signals and slots
    // we need the class to be declared in the header file.

    // MyThread.h 
    // Include missing headers
    class MyThread : public QThread
    {
      Q_OBJECT
      protected:
         void run(); // override

      public slots:
         void readData();
         void requestFinished(QNetworkReply * reply);
    };

    void MyThread::run() // override
    {
        // TODO: make it to quit the loop with some signal
        // initialize other objects before the loop
        QNetworkAccessManager* manager = new QNetworkAccessManager(this);
        // we want manager object to run on this thread
        manager->moveToThread(this); // the call maybe redundant here

        connect(manager , SIGNAL(finished(QNetworkReply*)),
            this, SLOT(requestFinished(QNetworkReply*)));

        QEventLoop loop;
        loop.exec();
    }

    // MyThread.cpp
    #include "MyThread.h"
    void MyThread::readData(QString strUrl)
    {
       // mind how exactly you compose the request (?)
       QNetworkRequest request(QUrl(strUrl));

       // here: usually this 'get' request is done from some slot while already in event loop
       QNetworkReply *reply = manager->get(request);
       // or maybe post request
       // QNetworkReply *reply = manager->post(request);

       // Error handling
       // connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
       //   this, SLOT(slotError(QNetworkReply::NetworkError)));
       // connect(reply, SIGNAL(sslErrors(QList<QSslError>)),
       //   this, SLOT(slotSslErrors(QList<QSslError>)));
   }

   void MyThread::requestFinished(QNetworkReply * reply)
   {
      QByteArray result = pReply->readAll();

      // do something with result
      pCallBack(result);
   }


   // MyDll.h
   __declspec(dllexport) void dllFunctionStart();
   // reading new data may depend on your app logic
   __declspec(dllexport) void dllFunctionRequestData();

   // MyDll.cpp 
    #include "MyDll.h"
    #include "MyThread.h"

    static MyThread* s_pThread;

    __declspec(dllexport) void dllFunctionStart()
    {
        // TODO: take care of releasing the thread object on quitting the thread
        s_pThread = new MyThread;
        s_pThread->start();
    }

    // reading new data may depend on your app logic
    __declspec(dllexport) void dllFunctionRequestData()
    {
        if (s_pThread)
            s_pThread->readData();
    }

附言我没有编译它,但这通常是解决此任务的方式。注意待办事项。

关于c++ - 在插件(DLL)中使用 Qt 网络模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33986189/

相关文章:

python - 调用 setParent 时 QMenu 显示不正确

c++ - 新标准中的 memcpy 生命周期初始化规则有哪些变化(如果有)?

c++ - Windows 上的 GetProcessTimes 不精确

windows - 模拟大型文件系统以测试 Windows 中的大型内存映射 (>5tb)

c++ - 如何在我的项目中包含常量

qt - Qml 如何恢复绑定(bind)?

c++ - 二维数组为函数参数时,这两种写法有什么区别?

c++ - 在字符串中搜索 UTF-8 代码点时有什么注意事项吗?

c++ - 暂停和恢复 pthread 的最佳解决方案是什么?

regex - 来自 dos 窗口的带有 "or"的 grep 命令行 (gnu grep)