Benjamin Kloster
48 posts
Hi everyone,
I found Casey's way of loading functions from DLLs for XInput to be a bit verbose, with lots of repeated names in slightly different capitalizations. For reference, here is the abridged version that just imports XInputGetState.

Using some C++11, it can be done a little more compact. I hope the comments make most of the idea clear, but for those unfamiliar with C++11, the features used here are:

1. The decltype keyword gives us the type of an expression, in this case, a function signature. Here, it's used to avoid using a typedef for the function signature. We can just use the signature of the original XInputGetState, as provided by the XInput.h header file.

2. Lambda functions. That's this weird thing:
 1  [](DWORD packetNumber, XINPUT_STATE* state) -> DWORD {...} 

It's basically an alternate way of defining functions. Here, we use it to initialize our XInputGetState_ with a stub function, without needing to declare that stub separately.

Now, the drawbacks of using this approach. First, it requires a bit of C++11 knowledge to understand. Especially decltype is not widely used outside of template libraries. And for the uninitiated, C++'s peculiar lambda syntax might cause high WTFs per minute.

Second, you probably won't be able to use this with older compilers. It *might* work with Visual Studio 2010, but I haven't tested it beyond the 2013 Community Edition, which handles it fine. I'm pretty sure it works with any reasonably new version of mingw. In any case, I think compatibility is a minor concern here, because it's part of platform-specific code anyway. It's not like this has to compile on Android or Raspberry PI.

The payoff is more compact code and, more importantly, less name pollution. The original version uses four names per imported function:

1. X_INPUT_GET_STATE for the preprocessor define
2. x_input_get_state for the function signature typedef
3. XInputGetStateStub for the stub function
4. XInputGetState_ for the drop-in replacement

The C++11 version manages with just one name, XInputGetState_.

Note that I don't think that either approach is objectively "better". They both have pros and cons. I mostly felt like sharing.

Happy coding!
Jeff Hutchins
1 posts