Forward declarations vs #include
only help with declaration circularity. But you have definition circularity. A multi-pass linker would resolve this if you were linking all the definitions together... but you aren't.
There are basically two ways to do this. First, you can change ELGetProcessIDApp
to a function pointer inside your utility library. Initially it points to some stub value in the utility library, and when the OS support library loads, it overwrites that function pointer with the OS-specific implementation.
Or, you can use a linker definition file to build an import library before the DLL actually exists. This will fix your linker problems by creating a set of circularly dependent DLLs. It can work, but it may also cause surprising load order effects and exhibits the global initialization ordering fiasco.
Or, just go with a single DLL, and limit your refactoring to splitting source files.