It's been a while since I had a need to use platform invoke to access native methods. When it comes to Interop I've had to use COM Interop much more frequently than platform invoke.
However, while trolling the C# fora for questions to answer, I ran across one about platform invoke that looked interesting. So to answer it I created a test solution, added a Win32 DLL project and a managed C# console app to call the DLL exports via platform invoke.
I kept getting the "EntryPointNotFoundException" whenever calling any of the DLL's exported functions. Running dumpbin /exports test.dll revealed that the functions were being exported. I assumed that the name mangled form was just an artifact of the way dumpbin displays function names.
The name mangled form, which C++ compilers use in part to create the illusion of class functions being part of a single object, is not just a display artifact. The name mangled form really is the symbol table entry. It should have clicked when I was able to access the entry point by it's ordinal (e.g., EntryPoint="#3"). Alas, it didn't.
The solution is to decorate standalone exported functions with extern "C" .... Dumpbin will then show the undecorated name in the list of exports.
As is so often the case when working in either a new area or an area that I haven't worked in for a while, it takes an effort to see what is right in front of you. To accept and, more importantly, understand the error messages. Dumpbin was literally showing me the name of the exported function but I wanted to believe that it was named what I wanted it to be named (the unmangled version).