Shared libraries and .h files
Asked Answered
E

5

17

I have some doubt about how do programs use shared library.

When I build a shared library ( with -shared -fPIC switches) I make some functions available from an external program. Usually I do a dlopen() to load the library and then dlsym() to link the said functions to some function pointers within my program. This approach does not involve including any .h file. Is there a way to avoid doing dlopen() & dlsym() and just including the .h of the shared library?

I guess this may be how C++ programs use code stored in system shared library, i.e - just including stdlib.h etc.

Exosphere answered 24/7, 2009 at 8:36 Comment(0)
M
76

Nick, I think all the other answers are actually answering your question, which is how you link libraries, but the way you phrase your question suggests you have a misunderstanding of the difference between headers files and libraries. They are not the same. You need both, and they are not doing the same thing.

Building an executable has two main phases, compilation (which turns your source into an intermediate form, containing executable binary instructions, but is not a runnable program), and linking (which combines these intermediate files into a single running executable or library).

When you do gcc -c program.c, you are compiling, and you generate program.o. This step is where headers matter. You need to #include <stdlib.h> in program.c to (for example) use malloc and free. (Similarly you need #include <dlfcn.h> for dlopen and dlsym.) If you don't do that the compiler will complain that it doesn't know what those names are, and halt with an error. But if you do #include the header the compiler does not insert the code for the function you call into program.o. It merely inserts a reference to them. The reason is to avoid duplication of code: The code is only going to need to be accessed once by every part of your program, so if you needed further files (module1.c, module2.c and so on), even if they all used malloc you would merely end up with many references to a single copy of malloc. That single copy is present in the standard library in either it's shared or static form (libc.so or libc.a) but these are not referenced in your source, and the compiler is not aware of them.

The linker is. In the linking phase you do gcc -o program program.o. The linker will then search all libraries you pass it on the command line and find the single definition of all functions you've called which are not defined in your own code. That is what the -l does (as the others have explained): tell the linker the list of libraries you need to use. Their names often have little to do with the headers you used in the previous step. For example to get use of dlsym you need libdl.so or libdl.a, so your command-line would be gcc -o program program.o -ldl. To use malloc or most of the functions in the std*.h headers you need libc, but because that library is used by every C program it is automatically linked (as if you had done -lc).

Sorry if I'm going into a lot of detail but if you don't know the difference you will want to. It's very hard to make sense of how C compilation works if you don't.

One last thing: dlopen and dlsym are not the normal method of linking. They are used for special cases where you want to dynamically determine what behavior you want based on information that is, for whatever reason, only available at runtime. If you know what functions you want to call at compile time (true in 99% of the cases) you do not need to use the dl* functions.

Madrigal answered 27/7, 2009 at 7:10 Comment(4)
you wrote: "For example to get use of dlsym you need libdl.so or libdl.a, so your command-line would be gcc -o program program.o -ldl." How do I tell the linker if it has to use shared or static libraries?Exosphere
Assuming you are using gcc? The linker will prefer the shared over the static by default. To make it prefer the static use the -static flag.Madrigal
Incidentally, when in doubt: prefer to use shared libraries. This is especially true for the system libraries. There are definitely uses for static libraries but they are usually special cases.Madrigal
looks like an answer to Do I need to explicitly include a common header file(in an include path folder) used in shared library? also. Thanks!Nordau
S
3

You can link shared libraries like static one. They are then searched for when launching the program. As a matter of fact, by default -lXXX will prefer libXXX.so to libXXX.a.

Splendiferous answered 24/7, 2009 at 8:42 Comment(0)
E
2

You need to give the linker the proper instructions to link your shared library.

The shared library names are like libNAME.so, so for linking you should use -lNAME

Call it libmysharedlib.so and then link your main program as:

gcc -o myprogram myprogram.c -lmysharedlib 
Evonevonne answered 24/7, 2009 at 8:42 Comment(0)
I
1

If you use CMake to build your project, you can use

TARGET_LINK_LIBRARIES(targetname libraryname)

As in:

TARGET_LINK_LIBRARIES(myprogram mylibrary)

To create the library "mylibrary", you can use

ADD_LIBRARY(targetname sourceslist)

As in:

ADD_LIBRARY(mylibrary ${mylibrary_SRCS})

Additionally, this method is cross-platform (whereas simply passing flags to gcc is not).

Islander answered 27/7, 2009 at 2:51 Comment(0)
M
1
  • Shared libraries (.so) are object files where the actual source code of function/class/... are stored (in binary)
  • Header files (.h) are files indicating (the reference) where the compiler can find function/class/... (in .so) that are required by the main code

Therefore, you need both of them.

Munos answered 30/12, 2021 at 1:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.