Linux程序设计——入门

xiaoxiao2021-02-28  25

Hello World

源代码

#include <stdio.h> #include <stdlib.h> int main() { printf("Hello World\n"); exit(0); }

编译、连接和运行程序

$ gcc -o hello hello.c $ ./hello

输出

Hello World

实验解析

使用C语言编译器gcc将C语言源代码转换为可执行文件hello。

应用程序管理

标准位置

/usr/bin /usr/local/bin /opt

头文件

使用头文件来提供对常量的定义和对系统函数及库函数调用的声明。

标准位置

/usr/include目录及其子目录

包含非标准位置头文件

$ gcc -I/usr/linux/include hello.c

搜索包含特定定义和函数原型的头文件

$ grep EXIT_ *.h

库文件

库是一组预先编译好的函数的集合,这些函数都是按照可重用的原则编写的。

标准位置

/lib和/usr/lib

默认情况下,C语言编译器(连接程序)仅仅搜索C语言库。即使把库文件放在标准目录中,还是需要在命令行中明确指明。

命名规范

lib+库名+.+库类型(a/o) .a代表传统的静态函数库 .so代表共享函数库

指定库文件

$ gcc -o hello hello.c /usr/lib/libm.a 或者 $ gcc -o hello hello.c -lm

包含非标准位置库文件

$ gcc -o hello -L/usr/linux/lib hello.c -lm

使用/usr/linux/lib目录中的libm库版本来编译和链接程序hello。

静态库

函数源文件bill.c和fred.c

#include <stdio.h> void bill(char *arg) { printf("bill: you passed %s\n", arg); } #include <stdio.h> void fred(int arg) { printf("fred: you passed %d\n", arg); }

生成目标文件(将要包含在库文件中)

使用-c选项,阻止编译器创建一个完成的程序

$ gcc -c bill.c fred.c

头文件lib.h

/* This is lib.h. It declares the functions fred and bill for users */ void bill(char *); void fred(int);

调用程序program.c

#include <stdlib.h> #include "lib.h" int main() { bill("Hello World"); exit(0); }

编译和测试(显式指定目标文件)

编译你的文件并将其与先前编译好的目标模块bill.o链接。

$ gcc -c program.c $ gcc -o program program.o bill.o $ ./program

输出

Bill: we passed Hello World

创建库文件

使用ar程序创建一个归档文件并将你的目标文件添加进去。

$ ar crv libfoo.a bill.o fred.o

编译和测试(使用库文件)

$ gcc -o program program.o libfoo.a $ ./program

查看哪些函数被包含在目标文件、函数库或可执行文件里

nm命令:显示二进制目标文件的符号表

$ nm program |grep T

输出

08048466 T bill 080484f4 T _fini 0804a000 d _GLOBAL_OFFSET_TABLE_ 080482cc T _init w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable 08049f10 d __JCR_LIST__ 080484f0 T __libc_csu_fini 08048490 T __libc_csu_init 0804843b T main 08048340 T _start 0804a020 D __TMC_END__ 08048370 T __x86.get_pc_thunk.bx

共享库

静态库的一个缺点

当你同时运行许多应用程序并且它们都使用来自同一个函数库的函数时,内存中就会有同一函数的多份副本,这将消耗大量宝贵的内存和磁盘空间。 当一个程序使用共享库时,它的链接方式是这样的:程序本身不再包含函数代码,而是引用运行时可访问的共享代码。当编译好的程序被装载到内存中执行时,函数引用被解释并产生对共享库的调用,如果有必要,共享库才被加载到内存中。 对Linux系统来说,负责装载共享库并解析客户程序函数引用的程序(动态加载器)是ld.so。

共享库的

/etc/ld.so.conf

查看程序所需要的共享库

$ ldd program

输出

linux-gate.so.1 => (0xb771c000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb754b000) /lib/ld-linux.so.2 (0x8007d000)

——《Linux程序设计 第四版》

转载请注明原文地址: https://www.6miu.com/read-1999983.html

最新回复(0)