It uses two core winapi functions. First is LoadLibrary(), the winapi function that loads a DLL into a process. It uses the name you specified for the DLL. Second is GetProcAddress(), the winapi function that returns the address of a function in a DLL. It uses the name of the function you specified. Then some plumbing runs that builds a stack frame for the function call, using the arguments you specified and it calls the function at the address it found.
So yes, this is very dynamic. This doesn't happen until your code actually lands on a statement that calls the pinvoked function. The technical term is "late binding" as opposed to the more common early binding used by the Windows loader for native code.