编写一包含函数(y=a*a+|b|)的c程序,把它编译成动态库文件,编写主程序调用该动态库文件中的函数,显示结果。编译链接成可执行文件。提交编译过程和执行结果

一、课程设计任务
编写一包含函数(y=a*a+|b|)的c程序,把它编译成动态库文件,编写主程序调用该动态库文件中的函数,显示结果。编译链接成可执行文件。提交编译过程和执行结果。

二、总体设计方案
①.设计一个函数SharedLibAip(int a,int b)用于完成y=aa+|b|
②.在一个c文件中构造SharedLibAip(int a,int b)函数
③.将含有SharedLibAip(int a,int b)函数编译成
.so格式的可链接文件
④.编译一个main函数程序用于调用动态库文件*.so,观察并记录结果
⑤.验证是否符合y=aa+|b|要求
三、详细设计/具体实现.
①.使用CentOS系统64位安装32位兼容包,用于可执行32位的命令和代码。
②.构造shlibexample.h(用于声明相关的宏定义和函数)和shlibexample.c(构造 SharedLibAip(a,b)实现y=a
a+|b|功能和 printf(“This is a shared library!\n”);表明调用了这一共享库)。

int SharedLibApi(a,b)
{
   if(b<0)
         b= -b;
   printf("This is a shared library!\n");
   return a*a+b;
}

③.使用命令:gcc -shared shlibexample.c -o libshlibexample.so -m32
将shlibexample.h和shlibexample.c编译成可链接的共享库文件libshlibexample.so.

④.编译主程序test.c用于实现调用共享库文件libshlibexample.so并声明调用其中的SharedLibApi(int a,int b),传入a,b从而传出y=a*a+|b|的值

⑤.编译:
gcc test.c -o myshared -L. -lshlibexample -ldl -m32

⑥.执行命令:export LD_LIBRARY_PATH=$PWD //将当前目录加入默认路径,否则main找不到依赖的库文件(将动态库文件和库文件放入默认路径下也可)

⑦.生成shared可执行文件,执行生成输入并得出结果。

四.课程设计结果及分析测试
执行命令输入a=22 b=-50 得出534使用了if(b<0) b= -b;
//使得b满足b=|b|

执行a=11 b=1 得出122
可实现y=a*a+|b|

测试:同时使用了装载时动态链接和运行时动态链接的效果.
①.装载时动态链接:使用SharedLibApi(a,b),因为动态链接库已经处于默认路径下所以可以直接调用这一函数
②.运行时动态链接:需要头文件:#include <dlfcn.h>dlopen打开一个库,获取句柄。
![]](https://img-blog.csdnimg.cn/20210716184722268.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MzA2OTg2,size_16,color_FFFFFF,t_70)
dlsym 在打开的库中查找符号的值。
dlclose 关闭句柄。
dlerror 返回一个描述最后一次调用dlopen、dlsym,或 dlclose 的错误信息的字符串。
五、课程设计总结
①.掌握如何在Liunx的64位环境下加入32位的兼容包的命令,对于一个函数如何成为可链接的成为.so的格式从程序全程编译的过程看(预编译——>编译——>汇编——>链接)动态链接相对于静态链接的优点是所占的空间更少,且动态链接在编译时不直接复制可执行代码,操作系统将需要的库文件加载到代码中,然后当代码运行到指定的代码时,去共享执行内存中已经加载共享库的执行代码。
②.发现当执行printf的时候,函数会先一步执行,并返回返回值。
③.观察运行时动态链接和加载是动态链接:加载时动态链接是在使用的时候直接对于函数调用时直接加载,在运行时动态链接是首先定义一个函数指针指向动态库后定义一个变量指向动态库的函数,后期在使用时直接调用这个变量即可同时在使用时要加 -lbl来表明使用共享库dlopen()等。
④.动态链接涉及运行时的链接及多个文件的转载,必需要有操作系统的支持,因为动态链接的情况下,进程的虚拟地址空间的分布会比静态链接情况下更为复杂,还有一些存储管理、内存共享、进程线程等机制在动态链接下也会有一些微妙变化。使用export LD_LIBRARY_PATH=$PWD使其为基本环境,使其动态库可以直接被调用。

六.使用代码

//shlibexample.h
#ifndef _SH_LIB_EXAMPLE_H_
#define _SH_LIB_EXAMPLE_H_
#define SUCCESS 0
#define FAILURE (-1)
#ifdef __cplusplus
extern "C"{
        #endif
        int SharedLibApi(int a,int b);
        #ifdef __cplusplus
        }
#endif
#endif

~                         
//shlibexample.c
#include <stdio.h>
#include "shlibexample.h"
int SharedLibApi(a,b)
{
        if(b<0)
        b= -b;
        printf("This is a shared library!\n");

        return a*a+b;
}

//test.c
#include <stdio.h>
#include "shlibexample.h"
#include <dlfcn.h>
int main()
{
        int a;
        int b;
        int y;
        printf("input:\na=");
        scanf("%d",&a);
        printf("b=");
        scanf("%d",&b);
        printf("------------------------\noutput:\n%d\n",SharedLibApi(a,b));
        //printf("change b: %d",b);/*do not changed*/

        void *handle=dlopen("libshlibexample.so",RTLD_NOW);
        if(handle==NULL){
        printf("OPEN ERROR:%s\n",dlerror());
        return FAILURE;
        }
        int (*func)(int a,int b);
        char *error;
        func=dlsym(handle,"SharedLibApi");
        if((error=dlerror())!=NULL)
        {
                printf("%s",error);
                return FAILURE;
        }
        printf("---------------------\ncalled\n%d\n",func(a,b));
//      func(a,b);
        dlclose(handle);
        return SUCCESS;
}      
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhong_Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值