C++ uses a full separate compilation model; you can even compile against code which hasn't been written. (This often occurs in large projects.) When you include a file, all you are doing is telling the compiler that the functions, etc. exist. You do not provide an implementation (except for inline functions and templates). In order to execute the code, you have to provide the implementation, by linking it into your application. This can occur in several different ways:
You have the source files; you compile them along with your sources, and link in the resulting objects.
You have a static library; you must link against it.
You have a dynamic library. Here, what you must do will depend on the implemention: under Windows, you must link against a .lib stub, and put the .dll somewhere where the runtime will find it when you execute. (Putting it in the same directory as your application is usually a good solution.)
I don't quite understand your need to call LoadLibrary
. The
only time I've needed this is when I've intentionally avoided
using anything in the library directly, and want to load it
conditionally, use GetProcAddr
to get the addresses of the
functions I need.
EDIT:
Since I was asked to clarify "linking": program translation (from the source to an executable) takes place in a number of steps. In traditional terms, each translation unit is "compiled" into an object file, which contains an image of the machine instructions, but with unfilled spaces for external references. For example, if you have:
extern void function();
in your source (probably via inclusion of a header), and you
call function
, the compiler will leave the address field of
the call instruction blank, since it doesn't know where the
function will be located. Linking is the process of taking all
of the object files, and filling in these blanks. One of the
object files will define function
, and the linker will
establish the actual address in the memory image, and fill in
the blank referring to function
with the address of function
in that image. The result is a complete memory image of the
executable. On the early systems I worked on: literally. The
OS would simply copy the executable file directly into memory,
and then jump into it. Things like virtual memory and shared,
write protected code segments make this a little more
complicated today, but for statically linked libraries or object
files (my first two cases above), the differences aren't that
great.
Modern system technologies have blurred the lines somewhat. For
example, most Java (and I think C#) compilers don't generate
classical object files, with machine code, but rather byte code,
and the compile and link phases, above, don't take place until
runtime. Some C++ compilers also only generate byte code, which
will be compiled when the code is "linked". This is done to
permit cross-module optimizations. And all modern systems
support dynamic linking: some of the blank addresses are left
blank until execution time. And dynamic linking can be implicit
or explicit: when it is implicit, the link phase will insert
information into the executable concerning the libraries it
needs, and where to find them, and the OS will link them,
implicitly, either when the executable is loaded, or on demand,
triggered by the code attempting to use one of the unfilled
address slots. When it is explicit, you normally don't have any
explicit referenced to the name in your code. In the case of
function
, above, for example, you wouldn't have any code which
directly called function
. Your code would, however, load the
dynamic library using LoadLibrary
(or dlopen
under Unix),
then request the address of a name, using GetProcAddr
(or
dlsys
), and call the function indirectly through the pointer
it received.