CoUninitialize "Access Violation"
Hi everyone,
I have an MFC app (with a CWinApp-derived object) that uses COM objects (Crystal Reports). The COM library is imported into my project via the #import directive. I'm using VStudio 6.0 sp5.
I've created a global object called _com_init:
struct ComInit {
ComInit() { ::CoInitialize(NULL); }
~ComInit() { ::CoUninitialize(); }
} _com_init_;
This way, I guarantee that COM will initialize before the _main() and terminate after the _main().
When my program reaches ~ComInit() and calls ::CoUninitialize(), I see the following message in my Debug Output Window:
First-chance exception in MyApp.exe (OLE32.DLL): 0xC0000005: Access Violation.
Any ideas? I've looked up other CoUninitialize threads in these forums, but couldn't figure out something that would solve my problem...
Thanks.
[898 byte] By [
sagmam] at [2007-11-18 13:41:21]

# 1 Re: CoUninitialize "Access Violation"
My initial thought was that you have global smart pointers that call Release() in their destructor, and CoUninitialize is being called before said destructor. However, in this case, the crash would be happening in/around Release(), rather than CoUninitialize().
Do you have global smart pointers? Can you verify that the above is not what is going on?
Also - why do you want COM to "initialize before the _main() and terminate after the _main()"?
# 2 Re: CoUninitialize "Access Violation"
I have no global smart pointers, as fas as I could tell. I wonder, however, if somewhere in MFC there is an initialization/termination of OLE... As far as I know, you can't call OleInit/Uninit AND call CoInit/Uninit in overlapping times. Maybe, when I call CoUninitialize, I actually don't need to call it, since MFC calls OleUninitialize() ... :-/
It's just a thought, but are there any other things I should check?
sagmam at 2007-11-11 2:10:18 >

# 3 Re: CoUninitialize "Access Violation"
Something to try:
Perhaps you could try making your ComInit object a local variable in main?
int main( void )
{
ComInit ci;
{
// rest of main() goes here...
}
}
# 4 Re: CoUninitialize "Access Violation"
You can't really have a CoInitialize and CoUninitialize outside of the main loop.
So why is this ? Because the app shuts down COM on executing anyway, but does it in an unclean fashion (to cope with GPFs etc).
Also, bear in mind if you get a GPF when calling CoUninitilize it normally means that one or more of your COM object has not been released before calling it.
All COM objects should be released before calling CoUninitialize and the best way to do this is to use smart pointer classes such as CComPtr or the ones defined when using #import.
Also bear in mind that if you have a COM method which takes a pointer to a pointer of an interface e.g.
HRESULT GetInterface(IMyInterface **ppInterface);
it is standard COM practice to assume that the interface is going to be released by the client, and not the server. This has tripped me up a couple of times when dealing with such engines as DirectX.
Again, the best way of handling this situation is something like as follows :
CComPtr<IMyInterface> pMyInterface;
pComObject->GetInterface(&pMyInterface);
which ensures that the interface is released when the CComPtr class is destroyed.
Also bear in mind some COM objects increase the ref count of interfaces which are passed in to 'keep them alive' so correct releasing of all interfaces is imperitive to prevent deadlocks from occurring which would also cause GPFs when calling CoUninitialize.
Darwen.
darwen at 2007-11-11 2:12:19 >

# 5 Re: CoUninitialize "Access Violation"
Hi all, thanks for your replies.
to vicodin: there is no 'main' function, it's an MFC app...
to Darwen:
All created objects are using smart pointers (local ones of course)in my app. Even my IApplication class is created like so:
IApplicationPtr pApp; // local variable
pApp->CreateInstance("Crystal Reports 9.Application");
as you can see, there are no global/local inteface objects or interface regular pointers lying around. I've checked EVERYWHERE.
I even checked with the debugger, to make sure that my IApplicationPtr object is destroyed when going out of scope. And it is.
Can there be a situation , where I use ONLY smart pointers, and still CoUninitialize traps an "Access violation" ?
As I mentioned earlier, my application doesn't break when this exception occurs. The "Access Violation" message only appears in the debug output window (as if COM itself catches this exception).
sagmam at 2007-11-11 2:13:22 >

# 6 Re: CoUninitialize "Access Violation"
Originally posted by sagmam
Hi all, thanks for your replies.
to vicodin: there is no 'main' function, it's an MFC app...
Originally posted by sagmam
This way, I guarantee that COM will initialize before the _main() and terminate after the _main().
You see why I would believe there is a main...(that you have control of)? :D
Apply the same concept - perhaps put the call to CoInitialize in the InitInstance of the CWinApp-derived class, and put the call to CoUninitialize in the ExitInstance...
as you can see, there are no global/local inteface objects or interface regular pointers lying around. I've checked EVERYWHERE.
You've barely posted any code - how can we see anything? I understand one is to infer that because you say
All created objects are using smart pointers (local ones of course)in my app, that this is so, but...
(as if COM itself catches this exception).
Perhaps, since your app is shutting down, the app is not in a state to be able to report problems. Since the AV appears to be coming from a function called in the dtor of a global object, it would seem that the CRT and possibly other libraries have already begun or even finished executing their cleanup code.
# 7 Re: CoUninitialize "Access Violation"
If your goal is to implement Crystal Reports functionality, you don't necessarily have to muck with the CoInitialize() and CoUnitialize() calls.
See this thread ( http://www.dev-archive.com/forum/showthread.php?s=&threadid=269870) for an example.