• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4893
  • Last Modified:

CoInitialize/CoCreateInstance

I am experiencing a problem with ActiveX. CoInitialize() is called once at the beginning of the application, and CoUninitialize() is called once at the end.  In between, CoCreateInstance() can be called several times for different COM objects - if CoCreateInstance() is called and then Release() is called 3 times, the next CoCreateInstance() fails with HRESULT = 0x800401F0 (CO_E_NOTINITIALIZED).  The documentation states that CoInitialize() only needs to be called once. Am I doing something wrong?
0
ejl
Asked:
ejl
  • 5
  • 4
1 Solution
 
MadshiCommented:
Yes, CoInitialize needs to be called only once.

Do I understand this right?
You call CoCreateInstance 1 time and then Release 3 times???
Please check that "Release" is only called once for every "CoCreateInstance".

Regards, Madshi.

P.S: Probably you don't want to hear this, but in Delphi (3 or higher) all this COM stuff is done from Delphi. I just love Delphi...   :-)
0
 
ejlAuthor Commented:
No, the pair is called 3 times - CoCreateInstance( ), then Release( ), in that order, 3 times.
0
 
MadshiCommented:
Can you please post a little sample program (that produces this error) as a comment. Perhaps I can see something.
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
ejlAuthor Commented:
Some code fragments are below.  I have also noticed, in a small test program I have, that if I call CoInitialize( ) in a main thread, then spin off another thread and call CoCreateInstance( ), I get the same return code - CO_E_NOTINITIALIZED.  Again, I understand from the documentation that CoInitialize( ) should be a one-time per-process call.

In the view constructor:

CdcsView::CdcsView()
{
    ...

    HRESULT hr;

    hr = CoInitialize(NULL);
    ....
    }


The COM object creation and destruction. There is some extraneous code in here, but this is just about all there is to the sequence.

E_CommonBellGroup::E_CommonBellGroup()
{
    USES_CONVERSION;

    NodeType       = tiCommonBellGroup;

    sGroupNo     = "";
    Description = "Description";
    sServiceCat  = "";
    sTrafficCat  = "";
    sQueueLength = "";
    sLIMNo       = "";
    sMagNo       = "";
    sBoardPos    = "";
    sIndivPos    = "";
    sCustomerNo  = "";

    HRESULT hr;

    hr = CoCreateInstance(CLSID_MDCommand,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_IMDCommand,
                          (void**) &m_pCmd);

    if (FAILED(hr))
    {
      ...
    }

    hr = m_pCmd->init(T2OLE("CBELI"), 0);

    if (FAILED(hr))
    {
       ...
    }
}
//
////////////////////////////////////////////////////////////////////////////////
//
E_CommonBellGroup::~E_CommonBellGroup()
{
    m_pCmd->Release();
}

0
 
MadshiCommented:
Ooops, I can't see nothing wrong. But I'm no C-programmer.
Have you tried OleInitialize instead of CoInitialize? Don't know why that should help. But perhaps it's worth a try.
Have you tried calling CoInitializeEx(NULL,COINIT_MULTITHREADED) instead of CoInitialize?
Perhaps CoInitialize must really be called for every thread. I don't understand the documentation that way, either. But you know Microsoft... Perhaps this is the problem of your real application (not your test application), too?

Regards, Madshi.
0
 
ejlAuthor Commented:
Tried the CoInitializeEx( ) with COINIT_MULTITHREADED, but it fails because my COM objects are defined to be apartment-threaded.  However, after that suggestion, I did find an error code defined in winerror.h, different from the one I'm getting, that indicates that CoInitialize( ) must be initialized for each thread... strange. That may be the threaded case, but I'm still stuck with the other problem.  Anyway, thanks for the suggestions.
0
 
MadshiCommented:
Perhaps the other problem is a thread problem, too? I don't know what you're doing exactly. I'm programming a shell extension in the moment and I had to learn that my DLL is called in the context of different threads (though being loaded only once). So I think if I would use CoInitialize in this DLL I had to call it very often. Perhaps you should check if your application (that one with "the other problem") is perhaps called in the context of different threads, too.

Regards, Madshi.
0
 
ejlAuthor Commented:
The 'real' application is actually written by someone else on the team - I wrote the COM objects.  However, I have reviewed the code and although it is built using multi-threaded libraries, there is only a single thread ever used.  Also, it is repeatable problem - it never varies.  The CoCreateInstance( ) and Release( ) pair is called the same way every time, and it works 3 times, then fails.

Thanks again,
ejl
0
 
MadshiCommented:
Ok, but is it possible that the application is called by someone else? Do you only use COM objects or have you programmed a COM server? Because if you're called by someone else you can never be sure in which thread context this happens. And - it's the only thing I can think of, why you should have this problem...
Perhaps you should just display a MessageBox before each call to CoCreateInstance with GetCurrentThreadID as message text. If it's no thread problem, what could it be?

Regards, Madshi.

P.S: Now it is 21:45 (PM) here in good old Germany. So enjoy. I'll be back tomorrow...
0
 
lbrucherCommented:
There is a flaw in the doc about CoInitialize(). It needs to be called for EVERY thread in your app (and not just once as the doc says).
If you work with multiple threads and call it once only, this should solve your problem.

0

Featured Post

Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now