Here’s the scenario:
-COM DLL, loaded into the address space of the process that uses the DLL.
-Inside the DLL couple global variables exist (lets say var a, var b) and a global function.
-Process starts up, calls the global function and initializes globals a, b and calls CoInitialize(NULL) – The thread is an STA.
-Then same global function creates an STA COM object
Later in the program, same thread (the thread that called CoInitialize above and created STA COM object) calls same global C-Function (lets call it func()) in this DLL. In the scope of the C-function the state of the global variables is exactly as expected (ie. correctly initialized).
The minute the function func() invokes a COM method on the existing STA COM object, the COM object being in the same DLL sees completely different copies of the global variables (var a, var b). I took the address of both variables and they are completely different in the C-func as opposed to invoked COM objects function.
What is going on? I thought globals in same address space should be visible across the board.
It’s possible that two instances of your DLL are being loaded — one explicitly by the application that hosts your DLL, and the second through the COM subsystem via CoCreateInstance. The former will look in the DLL search path for the application’s process, while the latter will look in the registry for the location of the COM component that implements your COCLASS.
If your DLL has a DllMain (or the InitInstance function if it’s an MFC-based DLL), then you can breakpoint it and look at the hinstance argument (or AfxGetInstanceHandle if MFC) to see if (a) you initialize twice and (b) you see two different DLL instance handles. If so, then you’re definitely loading twice.
The DLL’s location in the file system matters, so you should see if there are copies in separate locations that might be separately loaded based on the rules I mentioned above.
In general, a COM DLL should never be loaded directly. You should break your functionality up into two DLLs, with a COM server DLL dedicated to the COM stuff. You can provide yourself an internal COCLASS interface that will enable you to pass your globals to the COM DLL, if you so wish.