www.digitalmars.com         C & C++   DMDScript  

D - DirectX com and D

reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
I've been trying to port some C code to D that uses DirectX (without the
DirectX SDK or linking to ddraw.dll implicitly)

but the code give an access violation when I try to use the interface I get
back from the create entry point in ddraw.dll
 this is the line where is all goes wrong, if the printf's (see the code at
the end of the posting) are removed then it gives an access violation error,
if they are compiled in then the app quitely closes

anyone got any ideas ?

I assume in D the C code
typedef struct IDirectDraw   FAR *LPDIRECTDRAW;
DECLARE_INTERFACE_( IDirectDraw, IUnknown )
{
... blal bla bla
}

is written
alias IDirectDraw             LPDIRECTDRAW;
interface IDirectDraw : IUnknown
{

... blal bla bla
}


the C code is basically; (and it works under win95 and win2K with VC++6 and
mingw)

static HMODULE ddlib = 0;
static LPDIRECTDRAW        directDraw            = 0;
typedef HRESULT (WINAPI * DIRECTDRAWCREATEFUNCPTR) (GUID FAR *,LPDIRECTDRAW
FAR *,IUnknown FAR *);

int ConnectTo( HWND hwnd ) {
  DIRECTDRAWCREATEFUNCPTR DirectDrawCreateFunc;
  // load direct draw library
  ddlib = (HMODULE)LoadLibrary( "ddraw.dll" );
  DirectDrawCreateFunc = (DIRECTDRAWCREATEFUNCPTR)GetProcAddress( ddlib,
"DirectDrawCreate" );
  if ( !DirectDrawCreateFunc )  { return 0; }
  if ( DD_OK != DirectDrawCreateFunc( 0, &directDraw, 0 ) ) { return 0; }
  if (DD_OK != directDraw->SetCooperativeLevel( appWnd, DDSCL_NORMAL ) ) {
return 0; }
return 1;
}

so I tried this in D

HMODULE ddModule; /*!< handle to ddraw.dll (if loaded) */
IDirectDraw directDraw; /*!< com interface to direct draw */
 ddModule = LoadLibraryA( "ddraw.dll" );

bit loadDirectXLibrary()
{
 if ( ddModule != null )
 {
  ddCreateFunc createFuncPtr;
  createFuncPtr = (ddCreateFunc)GetProcAddress( ddModule,
"DirectDrawCreate" );
  if ( createFuncPtr != null )
  {
   directDraw = null;
   if ( DD_OK == createFuncPtr( null, &directDraw, null ) )
   {
    if ( directDraw === null ) { showError( "Unable make direct draw com
object." ); }
    // we loaded it :)
    return true;
   }
  }
 }
return false;
}

void createDirectDrawSurfacesOn( HWND hwnd )
{
/* clean exit no error if printf is compiled in */
 printf( "c dd : %x, %x, %x, %x\n\n", (int)hwnd, (int)(void *)directDraw,
(int)&directDraw, (int)&tmpAddr );
/* blowes up here */
 if ( DD_OK != directDraw.SetCooperativeLevel( hwnd, DDSCL_NORMAL ) )
 {
  printf( "failed to set coop level\n" );
  showError( "Unable to set coorerative level for direct draw." );
 }

 printf( "I DID ACTUALLY set coop level\n" );
 if ( !createDirectXSurfaces() )
 {
  showError( "Unable to create direct draw surfaces." );
 }
}

with the Interfaces defined as
alias IID * REFIID;
alias IDirectDraw             LPDIRECTDRAW;
alias IDirectDrawSurface      LPDIRECTDRAWSURFACE;

alias IDirectDrawPalette      LPDIRECTDRAWPALETTE;
alias IDirectDrawClipper      LPDIRECTDRAWCLIPPER;
alias IDirectDrawColorControl LPDIRECTDRAWCOLORCONTROL;

interface IDirectDraw : IUnknown
{
 /*** IUnknown methods ***/
 HRESULT QueryInterface( REFIID riid, LPVOID * ppvObj);
 ULONG   AddRef();
 ULONG   Release();
  /*** IDirectDraw methods ***/
 HRESULT Compact();
 HRESULT CreateClipper( DWORD, LPDIRECTDRAWCLIPPER *, IUnknown * );
 HRESULT CreatePalette( DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE *,
IUnknown * );
 HRESULT CreateSurface( LPDDSURFACEDESC, LPDIRECTDRAWSURFACE *, IUnknown *);
 HRESULT DuplicateSurface( LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE * );
 HRESULT EnumDisplayModes( DWORD, LPDDSURFACEDESC, LPVOID,
LPDDENUMMODESCALLBACK );
 HRESULT EnumSurfaces( DWORD, LPDDSURFACEDESC,
LPVOID,LPDDENUMSURFACESCALLBACK );
 HRESULT FlipToGDISurface();
 HRESULT GetCaps( LPDDCAPS, LPDDCAPS );
 HRESULT GetDisplayMode( LPDDSURFACEDESC );
 HRESULT GetFourCCCodes( LPDWORD, LPDWORD );
 HRESULT GetGDISurface( LPDIRECTDRAWSURFACE * );
 HRESULT GetMonitorFrequency( LPDWORD );
 HRESULT GetScanLine( LPDWORD );
 HRESULT GetVerticalBlankStatus( LPBOOL );
 HRESULT Initialize( GUID * );
 HRESULT RestoreDisplayMode();
 HRESULT SetCooperativeLevel( HWND, DWORD );
 HRESULT SetDisplayMode( DWORD, DWORD,DWORD );
 HRESULT WaitForVerticalBlank( DWORD, HANDLE );
}
Dec 04 2002
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
Woke up this morning and thought "idiot boy" the reason this does not work
is simple

 interface IDirectDraw : IUnknown
 {
  /*** IUnknown methods ***/
  HRESULT QueryInterface( REFIID riid, LPVOID * ppvObj);
  ULONG   AddRef();
  ULONG   Release();
   /*** IDirectDraw methods ***/
  HRESULT Compact();
... bla bla bla
}

is complete rubbish, the function pointers are all out by 3 because unlike
the C++ source I don't need to redeclare the base interface methods.

So it all works now.

Walter : any chance that duplicated names in interfaces can cause a warning
?

Mike.

"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:asmh3k$1d2j$1 digitaldaemon.com...
 I've been trying to port some C code to D that uses DirectX (without the
 DirectX SDK or linking to ddraw.dll implicitly)

 but the code give an access violation when I try to use the interface I
get
 back from the create entry point in ddraw.dll
  this is the line where is all goes wrong, if the printf's (see the code
at
 the end of the posting) are removed then it gives an access violation
error,
 if they are compiled in then the app quitely closes

 anyone got any ideas ?

 I assume in D the C code
 typedef struct IDirectDraw   FAR *LPDIRECTDRAW;
 DECLARE_INTERFACE_( IDirectDraw, IUnknown )
 {
 ... blal bla bla
 }

 is written
 alias IDirectDraw             LPDIRECTDRAW;
 interface IDirectDraw : IUnknown
 {

 ... blal bla bla
 }


 the C code is basically; (and it works under win95 and win2K with VC++6
and
 mingw)

 static HMODULE ddlib = 0;
 static LPDIRECTDRAW        directDraw            = 0;
 typedef HRESULT (WINAPI * DIRECTDRAWCREATEFUNCPTR) (GUID FAR
*,LPDIRECTDRAW
 FAR *,IUnknown FAR *);

 int ConnectTo( HWND hwnd ) {
   DIRECTDRAWCREATEFUNCPTR DirectDrawCreateFunc;
   // load direct draw library
   ddlib = (HMODULE)LoadLibrary( "ddraw.dll" );
   DirectDrawCreateFunc = (DIRECTDRAWCREATEFUNCPTR)GetProcAddress( ddlib,
 "DirectDrawCreate" );
   if ( !DirectDrawCreateFunc )  { return 0; }
   if ( DD_OK != DirectDrawCreateFunc( 0, &directDraw, 0 ) ) { return 0; }
   if (DD_OK != directDraw->SetCooperativeLevel( appWnd, DDSCL_NORMAL ) ) {
 return 0; }
 return 1;
 }

 so I tried this in D

 HMODULE ddModule; /*!< handle to ddraw.dll (if loaded) */
 IDirectDraw directDraw; /*!< com interface to direct draw */
  ddModule = LoadLibraryA( "ddraw.dll" );

 bit loadDirectXLibrary()
 {
  if ( ddModule != null )
  {
   ddCreateFunc createFuncPtr;
   createFuncPtr = (ddCreateFunc)GetProcAddress( ddModule,
 "DirectDrawCreate" );
   if ( createFuncPtr != null )
   {
    directDraw = null;
    if ( DD_OK == createFuncPtr( null, &directDraw, null ) )
    {
     if ( directDraw === null ) { showError( "Unable make direct draw com
 object." ); }
     // we loaded it :)
     return true;
    }
   }
  }
 return false;
 }

 void createDirectDrawSurfacesOn( HWND hwnd )
 {
 /* clean exit no error if printf is compiled in */
  printf( "c dd : %x, %x, %x, %x\n\n", (int)hwnd, (int)(void *)directDraw,
 (int)&directDraw, (int)&tmpAddr );
 /* blowes up here */
  if ( DD_OK != directDraw.SetCooperativeLevel( hwnd, DDSCL_NORMAL ) )
  {
   printf( "failed to set coop level\n" );
   showError( "Unable to set coorerative level for direct draw." );
  }

  printf( "I DID ACTUALLY set coop level\n" );
  if ( !createDirectXSurfaces() )
  {
   showError( "Unable to create direct draw surfaces." );
  }
 }

 with the Interfaces defined as
 alias IID * REFIID;
 alias IDirectDraw             LPDIRECTDRAW;
 alias IDirectDrawSurface      LPDIRECTDRAWSURFACE;

 alias IDirectDrawPalette      LPDIRECTDRAWPALETTE;
 alias IDirectDrawClipper      LPDIRECTDRAWCLIPPER;
 alias IDirectDrawColorControl LPDIRECTDRAWCOLORCONTROL;

 interface IDirectDraw : IUnknown
 {
  /*** IUnknown methods ***/
  HRESULT QueryInterface( REFIID riid, LPVOID * ppvObj);
  ULONG   AddRef();
  ULONG   Release();
   /*** IDirectDraw methods ***/
  HRESULT Compact();
  HRESULT CreateClipper( DWORD, LPDIRECTDRAWCLIPPER *, IUnknown * );
  HRESULT CreatePalette( DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE *,
 IUnknown * );
  HRESULT CreateSurface( LPDDSURFACEDESC, LPDIRECTDRAWSURFACE *, IUnknown
*);
  HRESULT DuplicateSurface( LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE * );
  HRESULT EnumDisplayModes( DWORD, LPDDSURFACEDESC, LPVOID,
 LPDDENUMMODESCALLBACK );
  HRESULT EnumSurfaces( DWORD, LPDDSURFACEDESC,
 LPVOID,LPDDENUMSURFACESCALLBACK );
  HRESULT FlipToGDISurface();
  HRESULT GetCaps( LPDDCAPS, LPDDCAPS );
  HRESULT GetDisplayMode( LPDDSURFACEDESC );
  HRESULT GetFourCCCodes( LPDWORD, LPDWORD );
  HRESULT GetGDISurface( LPDIRECTDRAWSURFACE * );
  HRESULT GetMonitorFrequency( LPDWORD );
  HRESULT GetScanLine( LPDWORD );
  HRESULT GetVerticalBlankStatus( LPBOOL );
  HRESULT Initialize( GUID * );
  HRESULT RestoreDisplayMode();
  HRESULT SetCooperativeLevel( HWND, DWORD );
  HRESULT SetDisplayMode( DWORD, DWORD,DWORD );
  HRESULT WaitForVerticalBlank( DWORD, HANDLE );
 }
Dec 05 2002
parent "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:asnaq6$2gvl$1 digitaldaemon.com...
 Woke up this morning and thought "idiot boy" the reason this does not work
 is simple
LOL. That's happened to me so many times, that sometimes went I can't figure things out I just put it on the back shelf. Most of the time, when I least expect it, I'll think of the answer. Sometimes, I'll load up all about a problem in the morning, and then just go jogging. Gives me something to do while running, and I do my best thinking that way.
 Walter : any chance that duplicated names in interfaces can cause a
warning
 ?
Went around a few times with the semantics of interface functions, right now I think it's best to leave them as is and accumulate experience.
Dec 19 2002