The key to calling a program like a function is to load in the object code of the new program without wiping out the object code of the currently executing one. As you've already learned, joining object code from different files is linking, and so this special is called dynamic (or runtime) linking. Runtime linking is a normal and automatic part of most operating systems these days, since the object code for many libraries is not brought into the program file, but is left in a library `shared object'. This saves diskspace by not copying the library every time it is used in another program, but it means that it has to be brought in at runtime, when it is needed.

The difference with bringing in the code of another program is that this code was never linked against to begin with, and so the runtime link has to be specifically asked for. The function dlopen() is used for this, but bringing the code into the process is all it does. After that the code just sits there. The next step is to call the code, and the logical thing to call is main() since it is the function that starts the program.

There is a problem, however. The program which is already running has a main() also, and since function calls are translated into addresses at compile time, putting a call to main() in a program will just cause the program to call the start of itself, rather than the start of some new code. What is needed is to call the address of the new main() specifically, which is done with a function pointer. The remaining trick is to find what the value of that function pointer should be, i.e. the address of the new main(). A companion of dlopen() called dlsym() is provided for this; it basically searches through the dlopened code for the specified symbol, and returns the address of it.