Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. "CoInitialize has not been called." warning

"CoInitialize has not been called." warning

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 5 Posters 4.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bart_Vandewoestyne
    wrote on last edited by
    #1

    After migrating from Qt 5.13.2 to 5.14.0, our unit tests suddenly started spitting out the following warning:

    qt.network.monitor: Failed to subscribe to network connectivity events: "CoInitialize has not been called."
    qt.network.monitor: failed to start network status monitoring
    

    The moment this happens, the top of the call stack is as follows:

    Qt5Networkd.dll!QNetworkListManagerEvents::start() Line 594	C++
    Qt5Networkd.dll!QNetworkStatusMonitorPrivate::start() Line 652	C++
    Qt5Networkd.dll!QNetworkStatusMonitor::start() Line 677	C++
    Qt5Networkd.dll!QNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest & originalReq, QIODevice * outgoingData) Line 1479	C++
    Qt5Networkd.dll!QNetworkAccessManager::post(const QNetworkRequest & request, QIODevice * data) Line 893	C++
    Qt5Networkd.dll!QNetworkAccessManager::post(const QNetworkRequest & request, QHttpMultiPart * multiPart) Line 930	C++
    OurOwn.dll!OurOwnClass::someMethod(...)
    

    so this happens when we call QNetworkAccessManager::post from inside OurOwnClass::someMethod().

    Any ideas on what has changed between 5.13.2 and 5.14.0 that triggers this warning, and on how to fix it, are welcome!

    1 Reply Last reply
    0
    • B Bart_Vandewoestyne

      @manordheim said in "CoInitialize has not been called." warning:

      @Bart_Vandewoestyne Yeah, this specific bug was fixed in 5.15.1.

      Is there an official bug report for that specific bug? I've searched https://bugreports.qt.io/ but cannot find it :-( Would be nice to know what commit(s) fix(es) it, so we can apply a patch to our local 5.15.0 vendor branch.

      B Offline
      B Offline
      Bart_Vandewoestyne
      wrote on last edited by
      #15

      @Bart_Vandewoestyne said in "CoInitialize has not been called." warning:

      Is there an official bug report for that specific bug? I've searched https://bugreports.qt.io/ but cannot find it :-( Would be nice to know what commit(s) fix(es) it, so we can apply a patch to our local 5.15.0 vendor branch.

      Bugreport: https://bugreports.qt.io/browse/QTBUG-84031
      Patch: https://codereview.qt-project.org/c/qt/qtbase/+/305169

      Thanks to @manordheim !
      I consider this issue fixed. All I must do is wait for 5.15.1 and test again :-)

      B 1 Reply Last reply
      1
      • B Offline
        B Offline
        Bonnie
        wrote on last edited by Bonnie
        #2

        It seems that there are some new internal classes which use COM APIs in Windows.
        Have you ever moved QNetworkAccessManager to another thread?
        I think this is probably the reason because CoInitialize needs to be called in every thread calling COM APIs.

        B 1 Reply Last reply
        2
        • B Offline
          B Offline
          Bart_Vandewoestyne
          wrote on last edited by
          #3

          I did come across https://bugreports.qt.io/browse/QTBUG-84031 in my search, and the commit that fixes it: https://github.com/qt/qtbase/commit/f1f0aa4a3a7d364b5110122a8f77079a7742c4e9
          Apparently, this fix will be included in Qt 5.15.1 (to be released in August 2020), so I'll definitely try with that version to see if the warning goes away.

          In the meanwhile, I'll double-check our code tomorrow to see if we are moving a QNetworkAccessManager object to another thread somewhere.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            manordheim
            wrote on last edited by
            #4

            Hello! With 5.14.0 the QNetworkStatusMonitor was added. Without knowing more (and assuming it was not moved across threads); was QNetworkAccessManager::post called from a different thread than it was created in? Otherwise I'm not sure what would cause it from looking at the stacktrace and the code. But if that's the case then that's not really supported: Since QNetworkAccessManager is based on QObject, it can only be used from the thread it belongs to.

            B 1 Reply Last reply
            2
            • B Bonnie

              It seems that there are some new internal classes which use COM APIs in Windows.
              Have you ever moved QNetworkAccessManager to another thread?
              I think this is probably the reason because CoInitialize needs to be called in every thread calling COM APIs.

              B Offline
              B Offline
              Bart_Vandewoestyne
              wrote on last edited by
              #5

              @Bonnie Yes, apparently, there is one place in our code where the QNetworkAccessManager object is moved to another thread. However, to the best of my knowledge, we are only using our QNetworkAccessManager object in the thread it belongs to.

              You write that CoInitialize needs to be called in every thread calling COM APIs... Do you have any idea how we can make sure that this is the case after moving our QNetworkAccessManager object to a different thread?

              JonBJ 1 Reply Last reply
              0
              • B Bart_Vandewoestyne

                @Bonnie Yes, apparently, there is one place in our code where the QNetworkAccessManager object is moved to another thread. However, to the best of my knowledge, we are only using our QNetworkAccessManager object in the thread it belongs to.

                You write that CoInitialize needs to be called in every thread calling COM APIs... Do you have any idea how we can make sure that this is the case after moving our QNetworkAccessManager object to a different thread?

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #6

                @Bart_Vandewoestyne
                You could call the necessary CoInitialize() immediately before/after moving your QNetworkAccessManager object to a different thread (call from the destination thread)?

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  Bart_Vandewoestyne
                  wrote on last edited by Bart_Vandewoestyne
                  #7

                  @manordheim, I am still fighting with this issue, but probably getting closer to nailing it down. Here's the situation: we have some kind of wrapper class, let's call it Wrapper, that has a member of type QNetworkAccessManager and of QThread:

                  class Wrapper :: public QObject
                  {
                  ...
                  private:
                      QNetworkAccessManager mvNetworkAccessManager;
                      QThread mvThread;
                  }
                  

                  Inside Wrapper's constructor, we move mvNetworkAccessManager to another thread that we then start:

                  Wrapper::Wrapper()
                      : mvNetworkAccessManager(this)
                  {
                      ... some logging with QThread::currentThreadId() to print the thread ID ...
                  
                      this->moveToThread(&mvThread);
                      mvThread.start();
                  }
                  

                  The QNetworkAccessManager::post method gets called from a member function of the Wrapper class:

                  void Wrapper::doThePost()
                  {
                      ...
                      ... some logging with QThread::currentThreadId() to print the thread ID ...
                      reply = mvNetworkAccessManager.post(... stuff ...)
                      ...
                  }
                  

                  The currentThreadId() that gets printed from the constructor is different from the currentThreadId() that gets printed from doThePost(). Am I right if I say that this is the problem?

                  To be able to call CoInitializeEx from the thread where the post() method is called, I changed the constructor code as follows:

                      this->moveToThread(&mvThread);
                      connect(&mvThread, &QThread::started, this, &Wrapper::mpHandleThreadStarted);
                      connect(&mvThread, &QThread::finished, this, &Wrapper::mpHandleThreadFinished);
                      mvThread.start();
                  

                  with

                  void ICNetworkAccessManager::mpHandleThreadStarted()
                  {
                      ... some logging with QThread::currentThreadId() to print the thread ID ...
                  
                      HRESULT hr;
                      hr = CoInitializeEx(0, COINIT_MULTITHREADED);
                      if (FAILED(hr))
                      {
                         ... print failure ...
                      }
                      else
                      {
                          ... print success ...
                      }
                  }
                  

                  and

                  void ICNetworkAccessManager::mpHandleThreadFinished()
                  {
                      ... some logging with QThread::currentThreadId() to print the thread ID ...
                      
                      CoUninitialize();
                  }
                  

                  From the logging in the mpHandleThreadStarted method, I can see that I am calling CoInitializeEx from the same thread as the one where I call my QNetworkAccessManager::post. I also don't see the "CoInitialize has not been called " warning anymore, but unfortunately, the new warning (occurring at exactly the same location, when calling post()) is now

                  qt.network.monitor: Failed to subscribe to network connectivity events: "The application called an interface that was marshalled for a different thread."
                  

                  Before that warning, I also see

                  onecore\com\combase\dcomrem\stdid.cxx(725)\combase.dll!754896A6: (caller: 754B13B1) ReturnHr(1) tid(4490) 8001010E The application called an interface that was marshalled for a different thread.
                  onecore\com\combase\dcomrem\stdid.cxx(725)\combase.dll!754896A6: (caller: 754B13B1) ReturnHr(2) tid(4490) 8001010E The application called an interface that was marshalled for a different thread.
                  onecore\com\combase\dcomrem\stdid.cxx(725)\combase.dll!754896A6: (caller: 754B13B1) ReturnHr(3) tid(4490) 8001010E The application called an interface that was marshalled for a different thread.
                  onecore\com\combase\dcomrem\stdid.cxx(725)\combase.dll!754896A6: (caller: 754B13B1) ReturnHr(4) tid(4490) 8001010E The application called an interface that was marshalled for a different thread.
                  

                  and so this is again where I'm stuck. Any ideas/suggestions on how to proceed are very welcome!

                  1 Reply Last reply
                  0
                  • M manordheim

                    Hello! With 5.14.0 the QNetworkStatusMonitor was added. Without knowing more (and assuming it was not moved across threads); was QNetworkAccessManager::post called from a different thread than it was created in? Otherwise I'm not sure what would cause it from looking at the stacktrace and the code. But if that's the case then that's not really supported: Since QNetworkAccessManager is based on QObject, it can only be used from the thread it belongs to.

                    B Offline
                    B Offline
                    Bart_Vandewoestyne
                    wrote on last edited by
                    #8

                    @manordheim said in "CoInitialize has not been called." warning:

                    [...] But if that's the case then that's not really supported: Since QNetworkAccessManager is based on QObject, it can only be used from the thread it belongs to.

                    Just to make sure I understand the Qt documentation right: what exactly do they mean by "it can only be used from the thread it belongs to". Do they mean "the thread it was created" or "the thread it was moved to"? I assume the second, but just need confirmation ;-)

                    jsulmJ 1 Reply Last reply
                    0
                    • B Bart_Vandewoestyne

                      @manordheim said in "CoInitialize has not been called." warning:

                      [...] But if that's the case then that's not really supported: Since QNetworkAccessManager is based on QObject, it can only be used from the thread it belongs to.

                      Just to make sure I understand the Qt documentation right: what exactly do they mean by "it can only be used from the thread it belongs to". Do they mean "the thread it was created" or "the thread it was moved to"? I assume the second, but just need confirmation ;-)

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      @Bart_Vandewoestyne said in "CoInitialize has not been called." warning:

                      "the thread it was created" or "the thread it was moved to"?

                      both

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      B 1 Reply Last reply
                      0
                      • jsulmJ jsulm

                        @Bart_Vandewoestyne said in "CoInitialize has not been called." warning:

                        "the thread it was created" or "the thread it was moved to"?

                        both

                        B Offline
                        B Offline
                        Bart_Vandewoestyne
                        wrote on last edited by
                        #10

                        @jsulm said in "CoInitialize has not been called." warning:

                        both

                        I'm afraid I cannot follow here... This is my understanding: if the object is created in thread A, and is not moved yet to a thread B, then it 'belongs to' thread A and all its slots will run on thread A. Once we move the object to thread B (using moveToThread), then it 'belongs to' thread B and from that moment on all its slots will run on thread B (if I understand things correctly, please correct me if I'm wrong).

                        Is that why you replied 'both'? Or am I fundamentally misunderstanding something here?

                        1 Reply Last reply
                        0
                        • B Offline
                          B Offline
                          Bart_Vandewoestyne
                          wrote on last edited by
                          #11

                          Using Qt 5.15.0, I was able to create the following minimal example that reproduces the problem:

                              QNetworkRequest request;
                              QHttpMultiPart* multiPart = new QHttpMultiPart();
                              QNetworkAccessManager mgr;
                              QThread thread;
                          
                              QObject::connect( &thread, &QThread::started,
                                               [&]() { mgr.post(request, multiPart); } );
                          
                              mgr.moveToThread(&thread);
                              thread.start();
                          
                              thread.quit();
                              thread.wait();
                          

                          and thus triggers the warning

                          qt.network.monitor: Failed to subscribe to network connectivity events: "CoInitialize has not been called."
                          qt.network.monitor: failed to start network status monitoring
                          

                          I think my two questions are now:

                          1. Is this a bug in Qt? Shouldn't the internal network monitoring code call CoInitialize at the right place?
                          2. If it is not a bug, then how to make the warning go away?
                          B M 2 Replies Last reply
                          0
                          • B Bart_Vandewoestyne

                            Using Qt 5.15.0, I was able to create the following minimal example that reproduces the problem:

                                QNetworkRequest request;
                                QHttpMultiPart* multiPart = new QHttpMultiPart();
                                QNetworkAccessManager mgr;
                                QThread thread;
                            
                                QObject::connect( &thread, &QThread::started,
                                                 [&]() { mgr.post(request, multiPart); } );
                            
                                mgr.moveToThread(&thread);
                                thread.start();
                            
                                thread.quit();
                                thread.wait();
                            

                            and thus triggers the warning

                            qt.network.monitor: Failed to subscribe to network connectivity events: "CoInitialize has not been called."
                            qt.network.monitor: failed to start network status monitoring
                            

                            I think my two questions are now:

                            1. Is this a bug in Qt? Shouldn't the internal network monitoring code call CoInitialize at the right place?
                            2. If it is not a bug, then how to make the warning go away?
                            B Offline
                            B Offline
                            Bonnie
                            wrote on last edited by
                            #12

                            @Bart_Vandewoestyne said in "CoInitialize has not been called." warning:

                            Is this a bug in Qt? Shouldn't the internal network monitoring code call CoInitialize at the right place?

                            I think it is.
                            And we all know there will be a fix in 5.15.1, don't we?
                            Unfortunately it seems to be delayed.
                            Just hope it could be released ASAP...

                            1 Reply Last reply
                            0
                            • B Bart_Vandewoestyne

                              Using Qt 5.15.0, I was able to create the following minimal example that reproduces the problem:

                                  QNetworkRequest request;
                                  QHttpMultiPart* multiPart = new QHttpMultiPart();
                                  QNetworkAccessManager mgr;
                                  QThread thread;
                              
                                  QObject::connect( &thread, &QThread::started,
                                                   [&]() { mgr.post(request, multiPart); } );
                              
                                  mgr.moveToThread(&thread);
                                  thread.start();
                              
                                  thread.quit();
                                  thread.wait();
                              

                              and thus triggers the warning

                              qt.network.monitor: Failed to subscribe to network connectivity events: "CoInitialize has not been called."
                              qt.network.monitor: failed to start network status monitoring
                              

                              I think my two questions are now:

                              1. Is this a bug in Qt? Shouldn't the internal network monitoring code call CoInitialize at the right place?
                              2. If it is not a bug, then how to make the warning go away?
                              M Offline
                              M Offline
                              manordheim
                              wrote on last edited by
                              #13

                              @Bart_Vandewoestyne Yeah, this specific bug was fixed in 5.15.1. But more recently the built-in connection status pre-check was dropped entirely from 5.15.1 (and 6.0).

                              B 1 Reply Last reply
                              0
                              • M manordheim

                                @Bart_Vandewoestyne Yeah, this specific bug was fixed in 5.15.1. But more recently the built-in connection status pre-check was dropped entirely from 5.15.1 (and 6.0).

                                B Offline
                                B Offline
                                Bart_Vandewoestyne
                                wrote on last edited by Bart_Vandewoestyne
                                #14

                                @manordheim said in "CoInitialize has not been called." warning:

                                @Bart_Vandewoestyne Yeah, this specific bug was fixed in 5.15.1.

                                Is there an official bug report for that specific bug? I've searched https://bugreports.qt.io/ but cannot find it :-( Would be nice to know what commit(s) fix(es) it, so we can apply a patch to our local 5.15.0 vendor branch.

                                B 1 Reply Last reply
                                0
                                • B Bart_Vandewoestyne

                                  @manordheim said in "CoInitialize has not been called." warning:

                                  @Bart_Vandewoestyne Yeah, this specific bug was fixed in 5.15.1.

                                  Is there an official bug report for that specific bug? I've searched https://bugreports.qt.io/ but cannot find it :-( Would be nice to know what commit(s) fix(es) it, so we can apply a patch to our local 5.15.0 vendor branch.

                                  B Offline
                                  B Offline
                                  Bart_Vandewoestyne
                                  wrote on last edited by
                                  #15

                                  @Bart_Vandewoestyne said in "CoInitialize has not been called." warning:

                                  Is there an official bug report for that specific bug? I've searched https://bugreports.qt.io/ but cannot find it :-( Would be nice to know what commit(s) fix(es) it, so we can apply a patch to our local 5.15.0 vendor branch.

                                  Bugreport: https://bugreports.qt.io/browse/QTBUG-84031
                                  Patch: https://codereview.qt-project.org/c/qt/qtbase/+/305169

                                  Thanks to @manordheim !
                                  I consider this issue fixed. All I must do is wait for 5.15.1 and test again :-)

                                  B 1 Reply Last reply
                                  1
                                  • B Bart_Vandewoestyne

                                    @Bart_Vandewoestyne said in "CoInitialize has not been called." warning:

                                    Is there an official bug report for that specific bug? I've searched https://bugreports.qt.io/ but cannot find it :-( Would be nice to know what commit(s) fix(es) it, so we can apply a patch to our local 5.15.0 vendor branch.

                                    Bugreport: https://bugreports.qt.io/browse/QTBUG-84031
                                    Patch: https://codereview.qt-project.org/c/qt/qtbase/+/305169

                                    Thanks to @manordheim !
                                    I consider this issue fixed. All I must do is wait for 5.15.1 and test again :-)

                                    B Offline
                                    B Offline
                                    Bart_Vandewoestyne
                                    wrote on last edited by
                                    #16

                                    @Bart_Vandewoestyne said in "CoInitialize has not been called." warning:

                                    [...] All I must do is wait for 5.15.1 and test again :-)

                                    For the record: Qt 5.15.1 is available from http://download.qt.io/official_releases/qt/5.15/5.15.1/.
                                    I tested again using this version, and the qt.network.monitor warnings no longer appear, so problem solved.

                                    Thanks!

                                    1 Reply Last reply
                                    0

                                    • Login

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • Users
                                    • Groups
                                    • Search
                                    • Get Qt Extensions
                                    • Unsolved