如何在Linux下添加函数库

如何在Linux下添加函数库,第1张

如何为Linux增加库

一. 静态库

在Linux下的静态库是以.a为后缀的文件

1. 建静态库

h1.c 源文件

#include<stdio.h>

void hello1()

{

printf(“the first hello!\n”)

}

h2.c 源文件

#include<stdio.h>

void hello2()

{

printf(“the second hello!\n”)

}

2.主程序

hello.c 源文件

#include<stdio.h>

int main()

{

hello1()

hello2()

return 0

}

输入命令:

gcc –c h1.c

gcc –c h2.c

ar –r libhello.a h1.o h2.o

ar –s libhello.a

ranlib libhello.a

最后再

gcc –static hello.c –L. –lhello –o hello即可生成可执行文件。注意要使用-static参数,否则生成的仍然是动态类型的文件,不过对于hello这个库则是采用静态方式来使用的而已。

二. 动态库

1.建动态库

#include<stdio.h>

void hello1()

{

printf(“the first hello!\n”)

}

h2.c 源文件

#include<stdio.h>

void hello2()

{

printf(“the second hello!\n”)

}

2. 主程序

hello.c 源文件

#include<stdio.h>

int main()

{

hello1()

hello2()

return 0

}

输入命令:

gcc –fPIC –g –c h1.c –o libh1.o

gcc –fPIC –g –c h2.c –o libh2.o

gcc –g –shared –W1 –o libh1.so libh1.o –lc

gcc –g –shared –W1 –o libh2.so libh2.o –lc

然后再将主程序与库相连进行编译

gcc –g hello.c –o hello –L. –lh1 –lh2

最后再将当前路径放到库查找路径中去

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATY

最后再执行./hello即可运行。

三. 动态库的查找过程

一旦连接器完成了自己的初始化工作,就查找程序所需要的库的名字。程序头中有一个指针指向dynamic段,它包含了动态连接的信息,dynamic段中的DT_STRTAB指向一个字符表,而其中的DT_NEEDED包含了一个相对于字符表的偏移,指向所需要的库名。

对于每一个库,连接器首先查找库文件位置,从本质上说是一个相当复杂的过程。DT_NEEDED所描叙的库文件名一般类似libXt.so.6 (Xt开发包, 版本6),库文件可能在任意的库文件目录中,还也可能有重名的文件。在我的系统中,这个库的实际文件名是/usr/X11R6/lib/libXt.so.6.0,最后的“.0”表示次版本号。

连接器查找下列几个地方:

 首先查看 .dynamic 段是否包含了一个叫DT_RPATH的项(它是一个以冒号分隔的库文件搜索目录列表)。这个项是在程序被连接器连接时,由命令行开关或者环境变量添加上去的。它常应用于子系统中,比如像数据库应用,我们要装载一些程序集合以及支持库到一个目录中去的时候。

 查看是否存在环境变量 LD_LIBRARY_PATH(它是一个以冒号分隔的库文件搜索目录列表)。这个项可以帮助开发者建立一个新版本的库,把他的路径添加到LD_LIBRARY_PATH中,把它和现存的可连接程序一同使用,用来测试新的库,

 连接器查看库高速缓存文件 /etc/ld.so.conf ,它包含了库名和路径的一个对应列表,如果库名存在,连接器就使用它对应的路径,用这个查找方法能够找到大部分的库(文件名不需要和要求完全符合,这点可以参考接下来的“库的版本”)。

 如果上叙的查找都失败,连接器就查找默认路径 /usr/lib ,如果库文件依旧没有找到,则显示一个错误然后退出。

连接器找到了库文件后,先打开它,然后读取ELF头,找到指向各个段的指针。连接器为库的代码段和数据段分配空间并映射到内存,随后是bss(不分配空间)。.通过库的 .dynamic 段,连接器添加这个库的符号表到符号表链,如果库所依赖的其它库没有装载的话,则添加那个库到装载队列中。

完成这个过程后,所有的库都已经被映射,loader在逻辑上拥有了一个全局的符号表,它是全部程序和被映射库的符号表的联合

一. 导出工具 exp

1. 它是 *** 作系统下一个可执行的文件 存放目录/ORACLE_HOME/bin

exp导出工具将数据库中数据备份压缩成一个二进制系统文件.可以在不同OS间迁移

它有三种模式:

a. 用户模式: 导出用户所有对象以及对象中的数据;

b. 表模式: 导出用户所有表或者指定的表;

c. 整个数据库: 导出数据库中所有对象。

2. 导出工具exp交互式命令行方式的使用的例子

$exp test/test123@appdb

Enter array fetch buffer size: 4096 >回车

Export file: expdat.dmp >m.dmp 生成导出的文件名

(1)E(ntire database), (2)U(sers), or (3)T(ables): (2)U >3

Export table data (yes/no): yes >回车

Compress extents (yes/no): yes >回车

Export done in ZHS16GBK character set and ZHS16GBK NCHAR character set

About to export specified tables via Conventional Path ...

Table(T) or Partition(T:P) to be exported: (RETURN to quit) >cmamenu 要导出的表名

. . exporting table CMAMENU 4336 rows exported

Table(T) or Partition(T:P) to be exported: (RETURN to quit) >要导出的表名n

Table(T) or Partition(T:P) to be exported: (RETURN to quit) >回车

Export terminated successfully without warnings.

3. 导出工具exp非交互式命令行方式的例子

$exp scott/tiger tables=(emp,dept) file=/directory/scott.dmp grants=y

说明:把scott用户里两个表emp,dept导出到文件/directory/scott.dmp

$exp scott/tiger tables=emp query=\"where job=\'salesman\' and sal\<1600\" file=/directory/scott2.dmp

说明:在exp里面加上导出emp的查询条件job='salesman' and sal<1600

(但我个人很少这样用,还是把满足条件的记录生成临时表后,再exp会方便一些)

$exp parfile=username.par

file=/directory1/username_1.dmp,/directory1/username_2.dmp

filesize=2000M log=/directory2/username_exp.log

参数文件username.par内容

userid=username/userpassword

buffer=8192000

compress=n

grants=y

说明:username.par为导出工具exp用的参数文件,里面具体参数可以根据需要去修改

filesize指定生成的二进制备份文件的最大字节数

(可用来解决某些OS下2G物理文件的限制及加快压缩速度和方便刻历史数据光盘等)

二.导入工具 imp

1. 它是 *** 作系统下一个可执行的文件 存放目录/ORACLE_HOME/bin

imp导入工具将EXP形成的二进制系统文件导入到数据库中.

它有三种模式:

a. 用户模式: 导出用户所有对象以及对象中的数据;

b. 表模式: 导出用户所有表或者指定的表;

c. 整个数据库: 导出数据库中所有对象。

只有拥有IMP_FULL_DATABASE和DBA权限的用户才能做整个数据库导入

imp步骤:

(1) create table (2) insert data (3) create index (4) create triggers,constraints

2.导入工具imp交互式命令行方式的例子

$ imp

Import: Release 8.1.6.0.0 - Production on 星期五 12月 7 17:01:08 2001

(c) Copyright 1999 Oracle Corporation. All rights reserved.

用户名: test

口令:****

连接到: Oracle8i Enterprise Edition Release 8.1.6.0.0 - 64bit Production

With the Partitioning option

JServer Release 8.1.6.0.0 - Production

导入文件: expdat.dmp>/tmp/m.dmp

输入插入缓冲区大小(最小为 8192 ) 30720>

经由常规路径导出由EXPORT:V08.01.06创建的文件

警告: 此对象由 TEST 导出, 而不是当前用户

已经完成ZHS16GBK字符集和ZHS16GBK NCHAR 字符集中的导入

只列出导入文件的内容(yes/no):no>

由于对象已存在, 忽略创建错误(yes/no):no>yes

导入权限(yes/no):yes>

导入表数据(yes/no):yes>

导入整个导出文件(yes/no):no>yes

. 正在将TEST的对象导入到 SCOTT

. . 正在导入表 "CMAMENU" 4336行被导入

成功终止导入,但出现警告。

3.导入工具imp非交互式命令行方式的例子

$ imp system/manager fromuser=jones tables=(accts)

$ imp system/manager fromuser=scott tables=(emp,dept)

$ imp system/manager fromuser=scott touser=joe tables=emp

$ imp scott/tiger file = expdat.dmp full=y

$ imp scott/tiger file = /mnt1/t1.dmp show=n buffer=2048000 ignore=n

commit=y grants=y full=y log=/oracle_backup/log/imp_scott.log

$ imp system/manager parfile=params.dat

params.dat 内容

file=dba.dmp show=n ignore=n grants=y fromuser=scott tables=(dept,emp)

4.导入工具imp可能出现的问题

(1) 数据库对象已经存在

一般情况, 导入数据前应该彻底删除目标数据下的表, 序列, 函数/过程,触发器等

数据库对象已经存在, 按缺省的imp参数, 则会导入失败

如果用了参数ignore=y, 会把exp文件内的数据内容导入

如果表有唯一关键字的约束条件, 不合条件将不被导入

如果表没有唯一关键字的约束条件, 将引起记录重复

(2) 数据库对象有主外键约束

不符合主外键约束时, 数据会导入失败

解决办法: 先导入主表, 再导入依存表

disable目标导入对象的主外键约束, 导入数据后, 再enable它们

(3) 权限不够

如果要把A用户的数据导入B用户下, A用户需要有imp_full_database权限

(4) 导入大表( 大于80M ) 时, 存储分配失败

默认的EXP时, compress = Y, 也就是把所有的数据压缩在一个数据块上.

导入时, 如果不存在连续一个大数据块, 则会导入失败.

导出80M以上的大表时, 记得compress= N, 则不会引起这种错误.

(5) imp和exp使用的字符集不同

如果字符集不同, 导入会失败, 可以改变unix环境变量或者NT注册表里NLS_LANG相关信息.

导入完成后再改回来.

(6) imp和exp版本不能往上兼容

imp可以成功导入低版本exp生成的文件, 不能导入高版本exp生成的文件

根据情况我们可以用

$ imp username/password@connect_string

说明: connect_string 是在/ORACLE_HOME/network/admin/tnsnames.ora

定义的本地或者远端数据库的名称

注意事项:

UNIX: /etc/hosts 要定义本地或者远端数据库服务器的主机名

win98: windows\hosts 和IP地址的对应关系

win2000: winnt\system32\drivers\etc\hosts


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7379258.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-05
下一篇 2023-04-05

发表评论

登录后才能评论

评论列表(0条)

保存