dlclose(handle);
}
如果这个程序名字叫foo.c,那么用下面的命令来编译:
gcc -o foo foo.c -ldl
5. 其他
5.1. nm命令
nm命令可以列出一个函数库文件中的符号表。它对于静态的函数库和共享的函数库都起作用。对于一个给定的函数库,nm命令可以列出函数库中定义
的所有符号,包括每个符号的值和类型。还可以给出在原程序中这个函数(符号)是在多少行定义的,不过这必须要求编译该函数库的时候加“-l”选项。
关于符号的类型,这里我们再多讨论一下。符号的类型是以一个字母的形式显示的,小写字母表示这个符号是本地(local)的,而大写字母则表示
这个符号是全局的(global,externel)。一般来说,类型有一下几种:T、D、B、U、W。各自的含义如下:T表示在代码段中定义的一般变量
符号;D表示时初始化过的数据段;B表示初始化的数据段;U表示没有定义的,在这个库里面使用了,但是在其他库中定义的符号;W,weak的缩写,表示如
果其他函数库中也有对这个符号的定义,则其他符号的定义可以覆盖这个定义。
如果你知道一个函数的名字,但是你不知道这个函数在什么库中定义的,那么可以用mn的“-o”选项和grep命令来查找库的名字。-o选项使得显示的每一行都有这个函数库文件名。例如,你要查找“cos”这个是在什么地方定义的,大致可以用下面的命令:
nm -o /lib* /usr/local/libGROUP ( /lib/libc.so.6
/usr/lib/libc_nonshared.a )
更多的信息可以参考texinfo文档中关于ld链接的脚本部分。一般的信息还可以参考: info:ld#Options
和info:ld#Commands,也可以参考info:ld#Option Commands。
5.4. GNU libtool
如果你正在编译的系统相很方便的移植到其他操作系统下,你可以使用GNU libtool来创建和安装这个函数库。GNU
libtool是一个函数库支持的典型的脚本。Libtool隐藏了使用一个可移植的函数库的负责性。Libtool提供了一个可以移植的界面来创建
object文件,链接函数库(静态或者共享的),并且安装这些库。它还包含了libltdl,一个可移植的动态函数库调入程序的wrapper。更多的
详细讨论,可以在看到。
5.5. 删除一些符号
在一个生产的文件中很多符号都是为了debug而包含的,占用了不少空间。如果空间不够,而且这些符号也许不再需要,就可以将其中一些删除。
最好的方法就是先正常的生成你需要的object文件,然后debug和测试你需要的一些东西。一旦你完全测试完毕了,就可以用strip去删
除一些不需要的符号了。Strip命令可以使你很方便的控制删除什么符号,而保留什么符号。Strip的具体用法可以参考其帮助文件。
另外的方法就是使用GNU
ld的选项“-S”和“-s”;“-S”会删除一些debugger的符号,而“-s”则是将所有的符号信息都删除。通常我们可以在gcc中加这样的参数“-Wl,-S”和“-Wl,-s”来达到这个目的。
摘要
下
面是一些例子,例子中我们会使用三种函数库(静态的、共享的和动态加载的函数库)。文件libhello.c是一个函数库,libhello.h
是它的头文件;demo_use.c则是一个使用了libhello函数库的。Script_static和script_dynamic分别演示如何以
静态和共享方式使用函数库,而后面的demo_dynamic.c和script_dynamic则表示演示如何以动态加载函数库的方式来使用它。
(2002-08-25 17:38:37)
By Wing
6. 更多的例子
下面是一些例子,例子中我们会使用三种函数库(静态的、共享的和动态加载的函数库)。文件libhello.c是一个函数库,
libhello.h是它的头文件;demo_use.c则是一个使用了libhello函数库的。Script_static和
script_dynamic分别演示如何以静态和共享方式使用函数库,而后面的demo_dynamic.c和script_dynamic则表示演示
如何以动态加载函数库的方式来使用它。
6.1. File libhello.c
#include
void hello(void)
{
printf("Hello, library world.
");
}
6.2. File libhello.h
void hello(void);
6.3. File demo_use.c
#include "libhello.h"
int main(void)
{
hello();
return 0;
}
6.4. 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
6.5. 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
6.6. File demo_dynamic.c
#include
#include
#include
typedef void (*simple_demo_function)(void);
int main(void)
{
const char *error;
void *module;
simple_demo_function demo_function;
module = dlopen("libhello.so", RTLD_LAZY);
if (!module)
{
fprintf(stderr, "Couldn't open libhello.so:
%s
",dlerror());
exit(1);
}
dlerror();
demo_function = dlsym(module, "hello");
if ((error = dlerror()))
{
fprintf(stderr, "Couldn't find hello: %s
", error);
exit(1);
}
(*demo_function)();
dlclose(module);
return 0;
}
6.7. 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