}

 

float in_to_cm(float in)

/* convert inches to centimeters */

{

 

return (in * 2.54);

 

}

 

float gal_to_l(float gal)

/* convert gallons to litres */

{

 

return (gal * 3.79);

 

}

 

float oz_to_g(float oz)

/* convert ounces to grams */

{

 

return (oz * 28.35);

 

}

 

You can use the +I linker option to register a routine as an initializer. Following are the commands to create libfoo.so and to register init_foo as the initializer:

$ cc -Aa -c libfoo.c

$ ld -b -o libfoo.so +I init_foo libfoo.o

To use this technique with multiple libraries, each library must have a unique initializer name. The following example program loads and unloads libfoo.so.

C Source for testlib.c #include <stdio.h> #include <dl.h> main()

{

float (*in_to_cm)(float), (*gal_to_l)(float), (*oz_to_g)(float); shl_t hndl_foo;

/*

*Load libfoo.so and find the required symbols:

*/

if ((hndl_foo = shl_load("libfoo.so", BIND_IMMEDIATE, 0)) == NULL)

perror("shl_load: error loading libfoo.so"), exit(1);

if (shl_findsym(hndl_foo, "in_to_cm", TYPE_PROCEDURE, (void *) &in_to_cm))

perror("shl_findsym: error finding in_to_cm"), exit(1);

if (shl_findsym(hndl_foo, "gal_to_l", TYPE_PROCEDURE, (void *) &gal_to_l))

perror("shl_findsym: error finding gal_to_l"), exit(1);

if (shl_findsym(hndl_foo, "oz_to_g", TYPE_PROCEDURE, (void *) &oz_to_g))

perror("shl_findsym: error finding oz_to_g"), exit(1);

/*

*Call routines from libfoo.so:

*/

printf("1.0in = %5.2fcm\n", (*in_to_cm)(1.0)); printf("1.0gal = %5.2fl\n", (*gal_to_l)(1.0)); printf("1.0oz = %5.2fg\n", (*oz_to_g)(1.0));

/*

*Unload the library:

*/

shl_unload(hndl_foo);

}

The following is the output of running the testlib program:

Output of testlib

Initializers for Shared Libraries 145