This works generally, and it is a common way to fix bugs or security vulnerabilities in the field, without recompiling the client programs. The key to success is ABI compatibility.
Symbol names are present within the DLL files, and the address of each function is looked up by symbol name when the DLL is loaded.
Specific gotchas that could prevent compatibility:
- Both DLL versions must have the same architecture (32 or 64 bit).
- The arguments and return types should match on both DLL versions.
- Also, the semantic meaning of each function call should at least be equivalent. If the DLL has an
add_widget
function that used to add widgets, but in the new DLL it removes widgets, there could be a problem.
- Calling conventions need to match between the old and new DLLs.
- If the new DLL is compiled with a different compiler, or with a different version of the same compiler, then symbols that are not declared
extern "C"
could break, because of name mangling.
- If standard library types are passed across the DLL boundary, then the standard library needs to be the same version (and the client programs need to use that version too).