Linux下使用动态链接库和静态链接库的项目建立及单步调试

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Linux下使用动态链接库和静态链接库的项目建立及单步调试
预览说明:预览图片所展示的格式为文档的源格式展示,下载源文件没有水印,内容可编辑和复制
Linux下使用动态链接库和静态链接库的项目建立及单步调试
在Linux下程序的主要调试工具是gdb,如喜欢用图形界面,可用insight。

下面对动态链接库和静态链接库的单步调试就是采用gdb+insight来完成的。

一、动态链接库的建立和单步调试
1、采用动态链接库的项目的建立
准备编写两个函数,一个用于查询当前日期getdate,一个用于查询当前时间gettime,并将这两个函数存于动态链接库my.so中。

为此,需要做以下几项工作。

1.1 编写用户接口文件datetime.h
/* datetime.h : 纵横软件制作中心雨亦奇编写, 2001-06-28. */ #ifndef __DA TETIME_H
#define __DA TETIME_H
/* 日期结构*/
typedef struct
{
int year;
int mon;
int day;
}DA TETYPE;
/* 时间结构*/
typedef struct
{
char hour;
char min;
char sec;
}TIMETYPE;
/* 函数原型说明*/
#ifdef SHARED
int (*getdate)(DA TETYPE *d);
#else
int getdate(DA TETYPE *d);
#endif
#ifdef SHARED
int (*gettime)(TIMETYPE *t);
#else
int gettime(TIMETYPE *t);
#endif
#endif
1.2 编写getdate.c,源程序如下:
* getdate.c : 纵横软件制作中心雨亦奇编写, 2001-06-28. */
#include "time.h"
#include "datetime.h"
int getdate(DA TETYPE *d)
{
long ti;
struct tm *tm;
time(&ti);
tm=localtime(&ti);
d->year=tm->tm_year+1900;
d->mon=tm->tm_mon+1;
d->day=tm->tm_mday;
}
在getdate函数中,先调用time取得以秒计的系统时间,再用
localtime函数转换一下时间结构,最后调整得到正确的日期。

1.3 编写gettime.c,源程序如下:
/* gettime.c : 纵横软件制作中心雨亦奇编写, 2001-06-28. */
#include "time.h"
#include "datetime.h"
int gettime(TIMETYPE *t)
{
long ti;
struct tm *tm;
time(&ti);
tm=localtime(&ti);
t->hour=tm->tm_hour;
t->min=tm->tm_min;
t->sec=tm->tm_sec;
}
gettime函数与getdate函数相仿,先用time函数取得以秒计的系统时间,再用localtime函数转换一下时间结构,最后返回当前的时间(不需调整)。

1.4 调用动态链接库的应用程序
/************************************/
/* 文件名称: dy.c */
/* 功能描述: 动态链接库应用示范程序*/
/* 程序编写: 纵横软件制作中心雨亦奇*/
/* 编写时间: 2001-06-28 */
/************************************/
#include "stdio.h" /* 包含标准输入输出文件*/
#include "stdlib.h"
#include "dlfcn.h" /* 包含动态链接功能接口文件*/
#define SOFILE "./my.so" /* 指定动态链接库名称*/
#define SHARED /* 定义宏,确认共享,以便引用动态函数*/
#include "datetime.h" /* 包含用户接口文件*/
main()
{
DA TETYPE d;
TIMETYPE t;
void *dp;
char *error;
puts("动态链接库应用示范");
dp=dlopen(SOFILE,RTLD_LAZY); /* 打开动态链接库*/
if (dp==NULL) /* 若打开失败则退出*/
{
fputs(dlerror(),stderr);
exit(1);
}
getdate=dlsym(dp,"getdate"); /* 定位取日期函数*/
error=dlerror(); /* 检测错误*/
if (error) /* 若出错则退出*/
fputs(error,stderr);
exit(1);
}
getdate(&d); /* 调用此共享函数*/
printf("当前日期: %04d-%02d-%02d\",d.year,d.mon,d.day); gettime=dlsym(dp,"gettime"); /* 定位取时间函数*/
error=dlerror(); /* 检测错误*/
if (error) /* 若出错则退出*/
{
fputs(error,stderr);
exit(1);
}
gettime(&t); /* 调用此共享函数*/
printf("当前时间: %02d:%02d:%02d\",t.hour,t.min,t.sec);
dlclose(dp); /* 关闭共享库*/
exit(0); /* 成功返回*/
}
LINUX下使用动态链接库,源程序需要包含dlfcn.h头文件,此文件定义了调用动态链接库的函数的原型。

下面详细说明一下这些函数。

(*)dlerror
原型为: const char *dlerror(void);
当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

(*)dlopen
原型为: void *dlopen (const char *filename, int flag);
dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。

(*)dlsym : 取函数执行地址
原型为: void *dlsym(void *handle, char *symbol);
dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。

由此地址,可以带参数执行相应的函数。

如程序代码: void (*add)(int x,int y); /* 说明一下要调用的动态函数add */
add=dlsym("xxx.so","add"); /* 打开xxx.so共享库,取add函数地址*/
add(89,369); /* 带两个参数89和369调用add函数*/
(*)dlclose : 关闭动态链接库
原型为: int dlclose (void *handle);
dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

1.5 编译过程
(*)编译生成动态链接库my.so
cc -shared -g -o my.so getdate.c gettime.c
(*)编译调用动态链接库的应用程序
gcc -g -o dy dy.c -ldl
以上调用gcc时,用-g,这样就可以在应用程序和库单步调试时,带有调试信息。

2、调试过程
2.1 在项目所在的路径下输入insight命令启动insight。

2.2 File-open打开dy程序,跳出“Make breakpoint pending on future share library load",
选择yes
2.3 设置断点,如line37,if (error)
2.4 run,(接着continue,如需要)
2.5 当程序运行到line37, if(error)时,step,程序运行到getdate(&d)行
2.6 step,程序跳到my.so库中的getdate函数中
2.7 继续各种调试工作
二、静态链接库的建立和单步调试
1、采用静态链接库的项目的建立
1.1 编写最简单的静态链接库
编写如下两个文件,注意放在同一目录中。

(*)myalib.h //静态库头文件
void test();
(*)myalib.c //静态库实现文件
#include
#include
void test()
{
printf("Hi, JH test for static_library!\");
}
1.2 调用静态库的测试程序
//main.c 测试静态库调用的程序
//要把函数的头文件包含进来,否则编译时会报错
#include "myalib.h"
int main(int argc,char* argv[])
{
test();
test();
return 0;
}
1.3 编译过程
(*)静态链接库的编译
gcc -g -c myalib.c
ar -rc libtest.a myalib.o
(*)测试应用程序的编译
gcc -g -I /media/ubuntu_data/worktop/static_library -o main.o -c main.c gcc -g -o main main.o libtest.a
2、调试过程
2.1 在项目所在的路径下输入insight命令启动insight。

2.2 File-open打开main程序
2.3 设置断点,如line6,int main的下一行
2.4 run
2.5 当程序运行到line6, step,程序运行到line7, test()
2.6 step,程序跳到libtest.a库中的test函数中2.7 继续各种调试工作。

相关文档
最新文档