The reason why the "unresolved symbol" error occurs is that the object file/library that contains (the implementation of the code represented by) the needed symbol is not included in the linking process.
One can call compiler and linker from command line.
One can manually write a "Makefile" that has commands to call compiler and linker.
One can create a "project file" that some build tool uses to write a Makefile. (MSVS both creates and is a build tool.)
Which ever method you use, there is a chance to forget to add all necessary files.
Ok, we did double-check that all files are involved.
It is still possible to forget to write implementation for some function.
Then remains a mismatch between function declaration and implementation. For a class member function that creates a compiler error, but with standalone functions linker has to deal with it. You seem to have this case, rather than the first.
We (and compiler) see in our code function declarations with name and argument types. The object file has a "symbol". The symbol is computed from declaration, but for
nextafter( double, double )
it will not look like "nextafter(double,double)
The string is "mangled", encoded.
There are tools to list symbols that an object file has, and they should have an option to show the symbols demangled back to human-readable strings.
For example, your linker did show both unmangled and mangled versions:
"void __cdecl MD5Update(struct MD5_CTX *,unsigned char *,unsigned int)"
(?MD5Update@@YAXPAUMD5_CTX@@PAEI@Z) // mangled
The name looks identical.
struct MD5_CTX *
seems to match