DirectX, COM and Access Violation

Henrik Eneroth zodiachus at gmail.com
Mon Feb 5 06:45:24 PST 2007


Hello there,

I've been trying to get Direct3D to work with D (or vice versa if you will) and keep running into some problems.
I checked around for translations of the DX headers and I found that existing efforts can vary a lot in implementation. So I tried to translate them myself and reduce dependencies to the standard library only. However, in the world of COM, nothing is what it seems... :)

At the present moment I've translated d3d9, d3d9types and d3d9caps, the minimum to get DX running it seems. I get some errors however.

Whenever I to call a DX function, I get an error saying "Access Violation". someone suggested that CoInitialize has to be called first, but that does not solve it. I looked around ( codesearch.google.com, lang:d ) and found a few different implementations. One of them differed from mine in a significant way.


This is what mine looks like (truncated to be readable):


Main file:
//-------------------//

IDirect3D9 * d3d;    // the pointer to our Direct3D interface
IDirect3DDevice9 * d3ddev;    // the pointer to the device class


bit initD3D(HWND hWnd)
{
    D3DDISPLAYMODE d3ddm;

    d3d = Direct3DCreate9(D3D_SDK_VERSION);
    assert(d3d);

    d3d.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); // Access Violation

    D3DPRESENT_PARAMETERS d3dpp;

    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT.D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFORMAT.D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFORMAT.D3DFMT_D16;


    d3d.CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev ); // Access violation if GetAdapterDisplayMode is commented out

    return true;
}

D3D9.d file:
//-------------------//
extern (Windows)
{
    export IDirect3D9 * Direct3DCreate9(UINT SDKVersion);

    interface IDirect3D9 : public IUnknown
    {

        /* ... */

        HRESULT CreateDevice(   UINT Adapter,D3DDEVTYPE DeviceType, HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface    );
    }

    /* ... */
}



This is essentially the other implementation:


Main file:
//-------------------//

IDirect3D9 d3d;    // Notice that this is not a pointer anymore
IDirect3DDevice9 d3ddev;    // Neither is this


bit initD3D(HWND hWnd)
{
    D3DDISPLAYMODE d3ddm;

    d3d = Direct3DCreate9(D3D_SDK_VERSION);
    assert(d3d);

    d3d.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); // No Access Violation anymore

    D3DPRESENT_PARAMETERS d3dpp;

    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT.D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFORMAT.D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFORMAT.D3DFMT_D16;


    d3d.CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev ); // Neither here

    return true;
}

D3D9.d file:
//-------------------//
extern (Windows)
{
    export IDirect3D9 Direct3DCreate9(UINT SDKVersion);

    interface IDirect3D9 : public IUnknown
    {

        /* ... */

        HRESULT CreateDevice(   UINT Adapter,D3DDEVTYPE DeviceType, HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9* ppReturnedDeviceInterface    ); // Notice that ppReturnedDeviceInterface is a simple pointer here
    } 

    /* ... */
}



Now the interesting thing is that if I try the other implementation, I do not get an access violation. However, I also get a blank window with nothing in it. D3D fails to even try to initialize it seems. I tried using the reference device instead of HAL, but the access violations remain even then suggesting there is some holy COM law I am continously violating or something.
I'm lost as to how to troubleshoot this. Any ideas?

By the way, I include these libs:
pragma (lib, "devrun\\x86\\d3d9d.lib"); // implib'd from d3d9d.dll
pragma (lib, "\\dm\\lib\\gdi32.lib");
pragma (lib, "\\dm\\lib\\uuid.lib");;


More information about the Digitalmars-d-learn mailing list