Linux库的创建及树莓派的IO口的初次使用

一、Linux库的概念

        C语言中的库的概念大都指函数库,即把功能性的函数写在一个 .c文件里,通过在头文件里声明这些函数。就可以在其他 .c 去引用那些函数,这样的编程方式也叫做模块化编程。使用模块化编程,使我们在调试的时候,更容易查找Bug,修改代码也方便。
        但是在实际编程中,有时并不希望使用者(使用函数库的人)看到函数源代码,就要打包函数库,让使用者看不到源代码,只是使用这些函数,这时就有三种打包后的三种库的概念:静态库、共享库和动态库。

静  态  库 概念:在程序运行之前,在编译的时候就加入到目标程序中。
优   点:1、静态库被打包到应用程序中,加载速度快;2、发布程序无需提供静态库,移植方便。
缺  点:1、链接时完成地拷贝到可执行我呢见中,被多次使用就有多份冗余拷贝,导致数据量大,耗内存;2、更新部署麻烦,发布麻烦
动  态  库 概念:共享库和动态库都差不多,在程序已经运行起来,再去调用库,临时使用它们。
优  点:1、连接时不复制,程序运行时动态调用库,可以节省内存;2、程序升级简单,如果只是修改函数的内容,可以不用编译程序即可实现升级优化。
缺  点:1、加载速度比静态库慢;2、发布程序需要提供依赖的动态库。

        言简意赅地说:静态库所实现的功能是程序 天生的,而动态库的功能是程序后天学来的。

二、静态库和动态库的创建及使用

1.静态库的创建

        静态库的创建一共分为两步:
        1. 将写有功能函数的 .c 打包编译成 .o 文件:gcc libxxx.c -c
        2..o 文件打包成 .a 文件:ar rcs libxxx.a libxxx.o
(1)使用方法:
        我们常把静态库以 “libxxx.a” 的形式来命名,而我们在使用的时候,需要“砍头去尾”,即不要“lib”和后缀,在编译主要程序时使用 “-l+静态库名字”的形式来连接静态库,比如demo1.c为主程序(有main函数),libtest.a为需要连接的静态库,有:

gcc demo1.c -ltest 

就可以把静态库编译到程序当中,但是如果libtest.a是我们自己创建的话,就需要再加上 “-L ./” 即在本地路径查找libtest.a 静态库。
(2)静态库实验
        需要创建两个C文件:test.cmain.ctest.c存放输出最大值,输出最小值和输出平均值等功能性函数,main.c 为主程序,建立一个头文件声明test.c里的函数。程序运行起来是这样的:
在这里插入图片描述
test.c的内容:

#include "library_conf.h"
 //比较最大值
int maxValue(int x,int y)
{
        if(x>y) return x;
        else    return y;
}
//比较最小值
int minValue(int x,int y)
{
        if(x<y) return x;
        else    return y;
}
//计算平均值
double averagerValue(int x,int y)
{
        double averager=0;
        averager=(double)(x+y)/2;
        return averager;
}

main.c的内容:

#include <stdio.h>
#include <stdlib.h>
#include "library_conf.h"

int main()
{

        int x,y;
        while(1){
                printf("input x:");
                scanf("%d",&x);
                printf("input y:");
                scanf("%d",&y);
                getchar();
                printf("Max:%d\n",maxValue(x,y));
                printf("Min:%d\n",minValue(x,y));
                printf("Averger:%.2f\n",averagerValue(x,y));
        }
        return 0;
}

library_conf.h文件的内容:

#ifndef LIBRARY_CONF_H
#define LINRARY_CONF_H

int maxValue(int x,int y);
int minValue(int x,int y);
double averagerValue(int x,int y);

#endif

把test.c打包成静态库:

gcc test.c -c
ar rcs libtest.a test.o

在这里插入图片描述
为了体现静态库的和平常的区别,我们可以先不用静态库来运行看看:
把test.c编译到main.c里面:

gcc test.c manin.c -o test1

在这里插入图片描述
把创建好的libtest.a静态库编译到main.c中:

gcc main.c -ltest -L ./

在这里插入图片描述

2.动态库的创建

(1)创建动态库:
        动态库的创建可以一部到位的把功能 .c 文件编译成 .so 文件,使用下面指令:

gcc -shared -fpic xxx.c -o libxxx.so

在这里插入图片描述
注: 指令中的“-shared” 指定生成动态库;“-fpic” 这是一种标准,用来生成位置无关码。
        动态库的使用和静态库的是一样的,但是动态库创建之后还不能直接使用,可以连接 main.c 来运行一下:
在这里插入图片描述

        它会出现运行错误,提示找不到文件,即找不到刚创建的 libtest.so 动态库,那是因为Linux系统在找动态库的时候,会在 /usr/lib/ 目录下找文件,如果不进行不把 libtest.so 放到那个目录下或者配置环境变量的话,运行就会出错。把文件放到 /usr/lib/ 就不做介绍,用 “mv” 指令就行,但是这种方式不推荐,因为这是我们创建的动态库,后面还要发布的呢,挪来挪去麻烦。
(2)配置动态库的路径:
        配置环境变量,不需要移动动态库,让程序可以在当前目录运行:

export LD_LIBRARY_PATH="这是动态库的路径"

在这里插入图片描述
        动态库是程序在运行时动态地调用函数,也就意味着:只要函数名和函数地参数保持不变,只修改函数的内容的话,可以不用编译main.c ,只要重新部署相关的动态库就可以做到功能改变,下面来试一下,把 test.c 中的 maxValue 函数的功能改成两数相加,即:

int maxValue(int x,int y)
{
      return x+y;
}

在这里插入图片描述
(3)用shell脚本实现多界面运行程序:
         虽然连接动态库的main程序能够正常运行起来了,但是切换到另一个界面的时候,就没办法运行,同样会出现,找不到文件的错误:
在这里插入图片描述
这时候,只需要写一个shell脚本就可以做到多界面运行,创建一个“start.sh”脚本文件,内容输入:

export LD_LIBRARY_PATH="动态库的路径"

./test1

然后添加可执行权限“-x”,
在这里插入图片描述

三、树莓派IO初次操作

       既然都在树莓派上完Linux了,如果不操作一下它的那IO口,那还不如在虚拟机上完嘞,所以先学一下简单的IO操作,可以让我们想开发Arduino一样操作树莓派的IO。
       wiringPi IO口操作库,我们装的Raspberry pi OS系统已经有了这个库,如果你用:gpio -v指令不会出现信息的话,请安装一下这个库:
在这里插入图片描述
使用:

gpio readall 

可以查看树莓派那40pin管教的管脚号:
在这里插入图片描述
如果你查不到的话,需要更新一下wiringPi,因为树莓派4B是比较新的板子,而系统自带的库比较老旧,就需要更新一下,请根据这个博文去操作:树莓派 gpio readall 出错的解决办法

1.wiringPi 配置管脚输出

       我的代码都是参照:树莓派 wiringPi 详解来写的,大家写的时候,也可以参照他的博客来写,下面是我的代码。

#include <wiringPi.h>
#include <stdio.h>
#define High 1
#define Low  0

#define Switch1 0

int main()
{
        int cmd;
        if(wiringPiSetup()==-1){
                printf("GPIO init fail!\n");
                return 0;
        }
        pinMode(Switch1,OUTPUT);
        digitalWrite(Switch1,HIGH);
 
        while(1){
                printf("请输入0/1[1:闭合继电器  0:断开继电器]:");
                scanf("%d",&cmd);
                getchar();
                if(cmd==High) digitalWrite(Switch1,HIGH);
                else if(cmd == Low)digitalWrite(Switch1,LOW);
                else printf("cmd error!\n");
        }
        return 0;
}

即我把GPIO_0给配置成输出模式,并使用键盘的 “1”和“0”键控制GPIO_0的输出,运行起来之后,readall也可以看到GPIO IO 的模式:
在这里插入图片描述
这样子,GPIO_0就可以输出高低电平,高电平为3.3V,低电平为0V,但是驱动能力有限,可以驱动LED,但是无法驱动没有光耦的继电器。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值