views:

109

answers:

5

When we build a programe,some symbols are to be resolved at link time(like those in a .lib),

but some can be resolved at run time(those in a .dll),

my doubt is that how does the compiler know about this, or how do we notify the compiler about this?

+1  A: 

You must declare a prototype for functions whose bodies are not available at compile time.

You do this by including the appropriate header (.h file) which will contain a definition like so:

int foo(int bar);

Note the lack of a body there.

Often with shared libraries there is also a layer of indirection where a struct containing function pointers is formed. When the library is loaded, it adjusts the function pointers to reference the functions contained in the shared library.

Borealid
I know about the `.h`, but how can compiler know whether `foo` should be resolved at link time or run time just based on that declaration?
wamp
@wamp: When you're linking against a dynamic library and not writing `dlopen` calls yourself, you pass an argument to the linker telling it which libraries to search for symbols. For example, `-lpthread` will cause gcc to link against libpthread.so and allows using `pthread_create`.
Borealid
A: 

Those that can be resolved at link time are; those that can't are then searched for in shared libraries at run time.

JohnR
But sometimes we get fatal error if not resolved, say, we aren't given chance to supply it at runtime
wamp
-1: not really true. If you call `notafunctionatall()`, it doesn't get searched for in shared libraries automatically.
Borealid
+3  A: 

When you link your code, the compiler searches both static and dynamic libraries for the undefined symbols. If it finds a dynamic symbol exported by a dynamic library, then it defers symbol resolution to runtime; if it finds a static symbol it resolves the symbol right away; and if it doesn't find the symbol at all, it reports an error (unless you're compiling a shared library, in which case it's OK).

You can examine the dynamic symbols exported by a shared library using nm -D.

caf
A: 

The linker does the job.

  • For static functions, the linker include the libraries into your excutable. Calls are to fixed positions in memory.
  • For dynamic libraries, the linker put a runtime "searcher" for the library. Dynamic Libraries publish the list of functions and its relative memory addresses. So, the runtime can fill the list of function pointers to them.

The original code for dynamic functions could be compiled as a call to a function pointer. [indeed, that's the job of the linker: replace the function calls to its references to produce the executable].

KikoV
How does compiler if it's **static** or **dynamic** funtion?
wamp
@wamp: dynamic symbols have a different type in the ELF header.
Borealid
@Borealid, can you elaborate about this?
wamp
@wamp: use `readelf` to inspect the symbols from an ELF file.
Borealid
A: 

The compiler needs to know the function declaration at compile time. The linker will then link to the declaration at link time to make aa executable.

For dynamically loaded libraries you insert a code to fetch the symbols at runtime using dlopen dlsym and dlclose. Now these function calls search for the symbols and if they are not found in the dynamic libraries they return error. Hence you need to handle this error as well. A dynamic library loading doesnt ensure symbols have been be resolved and linked. It still has to be present when the dynamic library is loaded.

EDIT : Fixed terrible grammar

Praveen S
So we **notify** the compiler in `c code`,not `compiler options` ?
wamp
@wamp - We link libraries using compiler option. However in source code the inclusion of a header file is done to ensure compiler is aware of the symbol.
Praveen S