Hi there,

I had a bit of a problem with one of the COM pointers in my program. I have a rendering class inside a DLL with a global class instance and a pointer to it. I make another pointer to its parent class in the main project and then have the pointer in DLL pass its address to the pointer in the main project through an interface.

In short there are two pointers that reference the class. One is defined inside the DLL as the child class, the other is defined in the main project as its parent class. Both seem to work fine.

Only trouble is I kept getting an issue on shutdown from the debugger stating that there was an unhandled exception on one of the COM pointers Release() method. I'm using smart pointers and the pointer in question resides inside the rendering class and is defined like so:

Code:
class D3DRenderer : public D3DInterface
{
public:

    D3DRenderer();
    ~D3DRenderer();

    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    static INT_PTR CALLBACK ChooseRender(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

....code omitted

protected:

    Microsoft::WRL::ComPtr<IDXGIFactory4>    mdxgiFactory;
I suspected that the somewhat convoluted way the project pointer references the class in the DLL may have caused an issue. I know COM objects when used with smart pointers will automatically keep track of the pointers that reference them and then reduce the reference count when those pointers go out of scope. When I made a call to AddRef() it fixed the issue. The program terminates normally with no unhandled exceptions or anything.

Only confusing thing is... I can only do this from inside the Dialog Box message handler, not the Window message handler:

This works:

Code:
// Message handler for dialog box.
LRESULT CALLBACK D3DRenderer::ChooseRender(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    LONG_PTR ptr = GetWindowLongPtr(GetParent(hDlg), 
    GWLP_USERDATA);
    static D3DRenderer** pD3DRenderer = reinterpret_cast<D3DRenderer**>(ptr);

    // Debug: Added function call from factory to see if this resolves issue. Even if it does, still need to know why - 9/3/24
    (*pD3DRenderer)->mdxgiFactory->AddRef();
Trying it in the windows message handler doesn't:

Code:
LRESULT CALLBACK D3DRenderer::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HINSTANCE hInstance;
    static D3DRenderer** _pD3DRenderer;
    static D3DRenderer** pD3DRenderer;

    switch (message)
    {
        case WM_CREATE:
	{
	    OutputDebugStringW(L"WM_CREATE entered \n\n");

	    hInstance = ((LPCREATESTRUCT)lParam)->hInstance;

	    CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
	    _pD3DRenderer = reinterpret_cast<D3DRenderer**>(pCreate->lpCreateParams);
	    SetWindowLongPtr(hWnd, GWLP_USERDATA (LONG_PTR)_pD3DRenderer);			

            LONG_PTR ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA);
            pD3DRenderer = reinterpret_cast<D3DRenderer**>(ptr);						

	    //Causes a fail
           (*pD3DRenderer)->mdxgiFactory->AddRef();
The dialog box is called in the window procedure further down inside a WM_COMMAND block in the switch case block.

Code:
case WM_COMMAND:
{
.... code omitted
    case IDM_OPTIONS:
        DialogBoxW(hInstance, MAKEINTRESOURCE(IDD_BASIC_RENDER_DIALOG), hWnd, D3DRenderer::ChooseRender);
So if I open the window and then hit the menu item "Options", then enter the dialog box and then shut everything down it's ok, provided I omit the AddRef() call from the window procedure. If I just try and run the window with the AddRef() call present it crashes.

I've no idea why. So time to ask on here!

Many Thanks in advance