To load dynamic libraries at runtime, the code for each platform is different. The below shows examples of loading a library at runtime and extracting a function pointer out of the library.

# Windows version

 1 2 HMODULE handle = LoadLibraryA("myLibrary.dll"); function_signature *pointerToFunction = (function_signature *)GetProcAddress(handle, "functionName"); 

Now that you get the basic idea, let's see a working example with comments explaining each step. This is one common way that you might choose to do it in practice.

In any non-trivial application, you could be loading many different libraries, and functions. Some of those libraries and functions may be optional. We will do this in small steps:

1. We will #define a macro for creating the function signature and stub.
2. We will use the macro to typedef a non-pointer version of the function
3. We will use the macro to make a stub function that can be used in place of a failed lookup.
4. At some arbitrary point (in main, in another function, or in a loader function that you create) we will load the library, testing to various versions.
5. If the library has loaded, we will then try to load a function pointer with the signature we defined.
6. If that function pointer is null, we will set it to the stub function.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include #include #include // First, we define a macro that // prints out the "signature" #define X_INPUT_GET_STATE(name) DWORD WINAPI name(DWORD dwUserIndex, XINPUT_STATE* pState) // Now we create a typedef for this function pointer typedef X_INPUT_GET_STATE(x_input_get_state); // The above will expand to this: // typedef DWORD WINAPI x_input_get_state(DWORD dwUserIndex, XINPUT_STATE* pState); // Now we create a "stub" in case the function couldn't be loaded X_INPUT_GET_STATE(XInputGetStateStub) { return(ERROR_DEVICE_NOT_CONNECTED); } int main(int argc, char* argv[]) { // First we try to load the "latest" version HMODULE x_input_lib = LoadLibraryA("xinput1_4.dll"); if ( ! x_input_lib ) { // If that version wasn't found, we try to load // the next latest, and so on. printf("Failed to load xinput 1.4\n"); x_input_lib = LoadLibraryA("xinput1_3.dll"); } if ( ! x_input_lib ) { // If all else fails, well, we handle this // whatever way we need to, here I quit out. printf("Failed to load xinputlib\n"); return(-1); } printf("XInput lib loaded\n"); x_input_get_state* functionPointer = (x_input_get_state*)GetProcAddress( x_input_lib, "XInputGetState" ); // Now we check the functionPointer to see if it // is null. if ( ! functionPointer ) { printf("Could not load XInputGetState function, using stub\n"); // If it's null, we set it to the stub functionPointer = XInputGetStateStub; } XINPUT_STATE ControllerState; if ( functionPointer(0,&ControllerState) == ERROR_SUCCESS) { printf("A controller is plugged in!\n"); } else { printf("No 0th controller found!\n"); } return(0); } 

# Mac/Linux version

 1 2 3 4 #include void *handle = dlopen ("myLibrary.dylib", RTLD_LAZY); function_signature *pointerToFunction = (function_signature *)dlsym(handle, "functionName");