Monday, December 28, 2009

Creating Libraries

The following are more examples of all three approaches (static, shared, and dynamically loaded libraries). File libhello.c is a trivial library, with libhello.h as its header. File demo_use.c is a trivial caller of the library. This is followed by commented scripts (script_static and script_dynamic) showing how to use the library as a static and shared library. This is followed by demo_dynamic.c and script_dynamic, which show how to use the shared library as a dynamically loaded library.

File libhello.c

/* libhello.c - demonstrate library use. */

#include <stdio.h>

void hello(void) {
printf("Hello, library world.\n");
}
//------------------------------------------------------------------

File libhello.h

/* libhello.h - demonstrate library use. */

void hello(void);
//------------------------------------------------------------------

File demo_use.c

/* demo_use.c -- demonstrate direct use of the "hello" routine */

#include <libhello.h>

int main(void) {
hello();
return 0;
}
//------------------------------------------------------------------

File script_static

#!/bin/sh
# Static library demo

# Create static library's object file, libhello-static.o.
# I'm using the name libhello-static to clearly
# differentiate the static library from the
# dynamic library examples, but you don't need to use
# "-static" in the names of your
# object files or static libraries.

gcc -Wall -g -c -o libhello-static.o libhello.c
//------------------------------------------------------------------

# Create static library.
ar rcs libhello-static.a libhello-static.o
//------------------------------------------------------------------

# At this point we could just copy libhello-static.a
# somewhere else to use it.
# For demo purposes, we'll just keep the library
# in the current directory.

# Compile demo_use program file.

gcc -Wall -g -c demo_use.c -o demo_use.o
//------------------------------------------------------------------

# Create demo_use program; -L. causes "." to be searched during
# creation of the program. Note that this command causes
# the relevant object file in libhello-static.a to be
# incorporated into file demo_use_static.

gcc -g -o demo_use_static demo_use.o -L. -lhello-static
//------------------------------------------------------------------

# Execute the program.

./demo_use_static
//------------------------------------------------------------------
//------------------------------------------------------------------

File script_shared

#!/bin/sh
# Shared library demo

# Create shared library's object file, libhello.o.

gcc -fPIC -Wall -g -c libhello.c
//------------------------------------------------------------------

# Create shared library.
# Use -lc to link it against C library, since libhello
# depends on the C library.

gcc -g -shared -Wl,-soname,libhello.so.0 \
-o libhello.so.0.0 libhello.o -lc
//------------------------------------------------------------------

# At this point we could just copy libhello.so.0.0 into
# some directory, say /usr/local/lib.

# Now we need to call ldconfig to fix up the symbolic links.

# Set up the soname. We could just execute:
# ln -sf libhello.so.0.0 libhello.so.0
# but let's let ldconfig figure it out.

/sbin/ldconfig -n .
//------------------------------------------------------------------

# Set up the linker name.
# In a more sophisticated setting, we'd need to make
# sure that if there was an existing linker name,
# and if so, check if it should stay or not.

ln -sf libhello.so.0 libhello.so
//------------------------------------------------------------------

# Compile demo_use program file.

gcc -Wall -g -c demo_use.c -o demo_use.o
//------------------------------------------------------------------

# Create program demo_use.
# The -L. causes "." to be searched during creation
# of the program; note that this does NOT mean that "."
# will be searched when the program is executed.

gcc -g -o demo_use demo_use.o -L. -lhello
//------------------------------------------------------------------

# Execute the program. Note that we need to tell the program
# where the shared library is, using LD_LIBRARY_PATH.

LD_LIBRARY_PATH="." ./demo_use
//------------------------------------------------------------------
//------------------------------------------------------------------

File demo_dynamic.c

/* demo_dynamic.c -- demonstrate dynamic loading and
use of the "hello" routine */

/* Need dlfcn.h for the routines to
dynamically load libraries */

#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>

/* Note that we don't have to include "libhello.h".
However, we do need to specify something related;
we need to specify a type that will hold the value
we're going to get from dlsym(). */

/* The type "simple_demo_function" describes a function that
takes no arguments, and returns no value: */

typedef void (*simple_demo_function)(void);


int main(void) {
const char *error;
void *module;
simple_demo_function demo_function;

/* Load dynamically loaded library */
module = dlopen("libhello.so", RTLD_LAZY);
if (!module) {
fprintf(stderr, "Couldn't open libhello.so: %s\n",
dlerror());
exit(1);
}

/* Get symbol */
dlerror();
demo_function = dlsym(module, "hello");
if ((error = dlerror())) {
fprintf(stderr, "Couldn't find hello: %s\n", error);
exit(1);
}

/* Now call the function in the DL library */
(*demo_function)();

/* All done, close things cleanly */
dlclose(module);
return 0;
}
//------------------------------------------------------------------

File script_dynamic

#!/bin/sh
# Dynamically loaded library demo

# Presume that libhello.so and friends have
# been created (see dynamic example).

# Compile demo_dynamic program file into an object file.

gcc -Wall -g -c demo_dynamic.c
//------------------------------------------------------------------

# Create program demo_use.
# Note that we don't have to tell it where to search for DL libraries,
# since the only special library this program uses won't be
# loaded until after the program starts up.
# However, we DO need the option -ldl to include the library
# that loads the DL libraries.

gcc -g -o demo_dynamic demo_dynamic.o -ldl
//------------------------------------------------------------------

# Execute the program. Note that we need to tell the
# program where get the dynamically loaded library,
# using LD_LIBRARY_PATH.

LD_LIBRARY_PATH="." ./demo_dynamic
//------------------------------------------------------------------

No comments:

Post a Comment