Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualRobTheBloke

Posted 31 July 2013 - 02:24 PM

Then you've got two options. 

1. Use C functions only. 

2. Use C++, along with some ungodly hacks, and revel in the ensuing maintenance nightmare!

 

The first goals 3 are achievable, but requirement 4 is a problem. The simplest way of doing this is with pure virtual interfaces (because you only need to export a single C function to create an instance of the main device class). To achieve all 4 goals, you'd need to use dbghelp.dll to unmangle the names returned from the DLL, and then find a way to invoke those methods via member function pointers (to classes you can't use, because you can't link to them). The (now ancient, and not particularly great for new projects) function binding interface from Scott Bilas (http://scottbilas.com/files/2001/gdc_san_jose/fubi_slides_outline.pdf) might provide some pointers, although expect to spend a lot of time digging through the PLE file, and how that relates to x64 (the code is 32bit). It's possible, but really really fugly.

A much simpler (and more efficient solution), is to simply use static libs for the renderer code. Compile D3D and OGL versions of your app, and then use a 3rd 'game-config' app to execute the relevant exe (based on whether the user has selected. D3D or GL). Any other libs you are using that aren't dependent on rendering code, should be fairly easy to move to DLLs that can be reused by both executables, which kinda gives you the same result, but somewhat in reverse (and you'll retain your sanity)

 

\edit 

I've just re-read your question, and I may have misread the bit about runtime switching. Ok, so if runtime switching is not a goal, then yes it's possible via the pimpl idiom (which should bury the platform specific stuff deep within the DLL, and leave your exported classes to expose only themselves [rather than their platform specific members]). Generally though, you'll end up with exactly the same amount of indirection as if you'd used pure virtual interfaces, and the code will be even more annoying to use in practice (pure virtual interfaces are the easiest way to achieve this goal, which will leave you with a runtime switchable DLL as a bonus). There are other ways to ensure ABI compatibility between DLL's, but in this particular case, your code would need to conform to some extremely rigid coding conventions (As an aside, I started putting together into an article for gamedev that explains how to do this, but that's on hold for the next few weeks whilst I move house!). Either don't bother, or go with virtual interfaces, or with pimpl. Those are your best options imho. 


#1RobTheBloke

Posted 31 July 2013 - 02:02 PM

Then you've got two options. 

1. Use C functions only. 

2. Use C++, along with some ungodly hacks, and revel in the ensuing maintenance nightmare!

 

The first goals 3 are achievable, but requirement 4 is a problem. The simplest way of doing this is with pure virtual interfaces (because you only need to export a single C function to create an instance of the main device class). To achieve all 4 goals, you'd need to use dbghelp.dll to unmangle the names returned from the DLL, and then find a way to invoke those methods via member function pointers (to classes you can't use, because you can't link to them). The (now ancient, and not particularly great for new projects) function binding interface from Scott Bilas (http://scottbilas.com/files/2001/gdc_san_jose/fubi_slides_outline.pdf) might provide some pointers, although expect to spend a lot of time digging through the PLE file, and how that relates to x64 (the code is 32bit). It's possible, but really really fugly.

A much simpler (and more efficient solution), is to simply use static libs for the renderer code. Compile D3D and OGL versions of your app, and then use a 3rd 'game-config' app to execute the relevant exe (based on whether the user has selected. D3D or GL). Any other libs you are using that aren't dependent on rendering code, should be fairly easy to move to DLLs that can be reused by both executables, which kinda gives you the same result, but somewhat in reverse (and you'll retain your sanity)


PARTNERS