当前位置: 首页 > news >正文

宜春招聘网站开发区招工太原首页推广

宜春招聘网站开发区招工,太原首页推广,网站建设挣钱的需要什么,做百度手机网站优✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、静态库 1.1、怎么做静态库 1.2、怎么使用静态库 1、静态库 1.1、怎么做静态库 在Linux环境下,通常使用GCC&am…

个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】

目录

1、静态库

1.1、怎么做静态库

1.2、怎么使用静态库


1、静态库

1.1、怎么做静态库

在Linux环境下,通常使用GCC(GNU Compiler Collection)编译器来编译源代码,并使用ar(archiver)工具来创建静态库。

  1. 编写源代码:首先,你需要有一些源代码文件,比如 x.c ,y.c ,z.c

  2. 编译源代码为对象文件:使用GCC编译器将源代码编译为目标文件(.o文件)

  3. 创建静态库:使用 ar工具将对象文件打包成静态库

头文件是一个手册提供函数的声明,告诉用户怎么用;.o提供实现,我们只需要补上一个main函数,调用头文件提供的方法,然后和.o进行链接,就能形成可执行

mymath.h

#pragma once // 防止头文件重复包含#include <stdio.h>int Add(int x,int y);

mymath.c

#include "mymath.h"int Add(int x,int y)
{return x + y;
}

mystdio.h

#pragma once #include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>#define LINE_SIZE 1024
#define FLUSH_NOW  1
#define FLUSH_LINE 2
#define FLUSH_FULL 4typedef struct _myFILE  
{unsigned int flags;int fileno;// 缓冲区char cache[LINE_SIZE];int cap;// 容量int pos;// 下次写入的位置
}myFILE;myFILE* my_fopen(const char* path,const char* flag);
void my_fflush(myFILE* fp);
ssize_t my_fwrite(myFILE* fp,const char* data,int len);
void my_fclose(myFILE* fp);

mystdio.c

#include "mystdio.h"myFILE* my_fopen(const char* path,const char* flag)
{int flag1 = 0;int iscreate = 0;mode_t mode = 0666;if(strcmp(flag,"r") == 0){flag1 = O_RDONLY;}else if(strcmp(flag,"w") == 0){flag1 = (O_WRONLY | O_CREAT | O_TRUNC);iscreate = 1;}else if(strcmp(flag,"a") == 0){flag1 = (O_WRONLY | O_CREAT | O_APPEND);iscreate = 1;}else {}int fd = 0;if(iscreate)fd = open(path,flag1,mode);else fd = open(path,flag1);if(fd < 0) return NULL;myFILE* fp = (myFILE*)malloc(sizeof(myFILE));if(fp == NULL) return NULL;fp->fileno = fd;fp->flags = FLUSH_LINE;fp->cap = LINE_SIZE;fp->pos = 0;return fp;
}
void my_fflush(myFILE* fp)
{write(fp->fileno,fp->cache,fp->pos);fp->pos = 0;
}
ssize_t my_fwrite(myFILE* fp,const char* data,int len)
{// 写入的本质是拷贝,条件允许就刷新memcpy(fp->cache + fp->pos ,data,len);// 考虑扩容与越界问题fp->pos += len;if((fp->flags&FLUSH_LINE) && fp->cache[fp->pos-1] == '\n'){my_fflush(fp);}return len; 
}
void my_fclose(myFILE* fp)
{my_fflush(fp);close(fp->fileno);free(fp);
}

main.c

#include "mymath.h"
#include "mystdio.h"
#include <string.h>
#include <stdio.h>int main()
{int a = 10;int b = 20;printf("%d + %d  = %d\n",a,b,myAdd(a,b));myFILE* fp = my_fopen("log.txt","w");if(fp == NULL) return 1;const char* message = "这是我写的...\n";my_fwrite(fp,message,strlen(message));my_fclose(fp);return 0;
}

编译并执行程序

[jkl@host lib]$ gcc main.c mymath.c mystdio.c
[jkl@host lib]$ ls
a.out  log.txt  main.c  mymath.c  mymath.h  mystdio.c  mystdio.h  
[jkl@host lib]$ ./a.out
10 + 20  = 30
[jkl@host lib]$ cat log.txt
这是我写的...

将.c文件(源文件)编译成.o文件(目标文件) [ -c选项告诉GCC只编译和汇编,但不链接]

gcc -c mymath.c  # 将mymath.c文件编译成.o文件,默认编译成mymath.o
gcc -c mystdio.c # 将mystdio.c文件编译成.o文件,默认编译成mystdio.o

 ​​​​​​

使用.h 文件和.o 文件编译main.c程序

[jkl@host roommate]$ ls
main.c  mymath.h  mymath.o  mystdio.h  mystdio.o
[jkl@host roommate]$ gcc main.c
/tmp/ccFk2rMI.o: In function `main':
main.c:(.text+0x21): undefined reference to `myAdd'
main.c:(.text+0x49): undefined reference to `my_fopen'
main.c:(.text+0x84): undefined reference to `my_fwrite'
main.c:(.text+0x90): undefined reference to `my_fclose'
collect2: error: ld returned 1 exit status

 gcc main.c 只编译了main.c文件,并没有包含对mymath.o 和 mystdio.h 的链接操作,因为main.c 依赖于mymath.h 和 mystdio.h 中声明的函数,因此仅编译main.c是不够的。

解决办法一:

gcc main.c mymath.o mystdio.o -o myexe

将.o文件 和.c文件一起编译链接。 

解决办法二:

将main.o也编译成.o文件

[jkl@host roommate]$ gcc -c main.c
[jkl@host roommate]$ ls
main.c  main.o  mymath.h  mymath.o  mystdio.h  mystdio.o
[jkl@host roommate]$ gcc mymath.o mystdio.o main.o -o myexe
[jkl@host roommate]$ ls
main.c  main.o  myexe  mymath.h  mymath.o  mystdio.h  mystdio.o
[jkl@host roommate]$ ./myexe
10 + 20  = 30
[jkl@host roommate]$ ls
log.txt  main.c  main.o  myexe  mymath.h  mymath.o  mystdio.h  mystdio.o
[jkl@host roommate]$ cat log.txt
这是我写的...

通过ar指令将所有.o文件打包: 

ar -rc libmyc.a *.o # 将所有.o文件打包成libmyc.a文件

r(replace) 选项表示替换库中已存在的文件

c(create) 选项表示创建一个新的库 。

1.2、怎么使用静态库

  • 方式一:直接使用打包的文件

为了更好的使用静态库,我们把前面打包的文件拷贝到另外的目录进行操作。

cp libmyc.a roommate/ # 将打包的文件拷贝到下级目录下
[jkl@host roommate]$ cp ../mymath.h . # 将.h文件拷贝到下级目录
[jkl@host roommate]$ cp ../mystdio.h .
[jkl@host roommate]$ ls
main.c  myexe  mymath.h  mymath.o  mystdio.h  mystdio.o

 直接使用gcc 编译

[jkl@host roommate]$ gcc main.c
/tmp/ccuZcLr1.o: In function `main':
main.c:(.text+0x21): undefined reference to `myAdd'
main.c:(.text+0x49): undefined reference to `my_fopen'
main.c:(.text+0x84): undefined reference to `my_fwrite'
main.c:(.text+0x90): undefined reference to `my_fclose'
collect2: error: ld returned 1 exit status

使用gcc 编译main.c 和 libmyc.a 

[jkl@host roommate]$ gcc main.c libmyc.a
[jkl@host roommate]$ ls
a.out  libmyc.a  main.c  mymath.h  mystdio.h
[jkl@host roommate]$ ./a.out
10 + 20  = 30
[jkl@host roommate]$ ls
a.out  libmyc.a  log.txt  main.c  mymath.h  mystdio.h
[jkl@host roommate]$ cat log.txt
这是我写的...
  •  方式二:将打包的文件拷贝到系统库中(严重不推荐)

我们可以将自己写的.h头文件写到/usr/bin/目录下。

我们可以将自己打包的方法实现文件写到/usr/bin54/目录下。 

 

查看拷贝的文件 

[jkl@host roommate]$ ls /usr/include/mymath.h
/usr/include/mymath.h
[jkl@host roommate]$ ls /usr/include/mystdio.h
/usr/include/mystdio.h
[jkl@host roommate]$ ls /usr/lib64/libmyc.a
/usr/lib64/libmyc.a

把上面的两步操作做完之后,我们可以直接编译main函数,头文件可以使用<>

main.c

#include <mymath.h>
#include <mystdio.h>
#include <stdio.h>
#include <string.h>int main()
{int a = 10;int b = 20;printf("%d + %d  = %d\n",a,b,myAdd(a,b));myFILE* fp = my_fopen("log.txt","w");if(fp == NULL) return 1;const char* message = "这是我写的...\n";my_fwrite(fp,message,strlen(message));my_fclose(fp);return 0;
}

直接使用gcc编译还是会报错,因为该方法的实现是我们自己写的,gcc/g++不认识,所以直接编译会报错。 

[jkl@host roommate]$ gcc main.c
/tmp/ccZqyRSO.o: In function `main':
main.c:(.text+0x21): undefined reference to `myAdd'
main.c:(.text+0x49): undefined reference to `my_fopen'
main.c:(.text+0x84): undefined reference to `my_fwrite'
main.c:(.text+0x90): undefined reference to `my_fclose'
collect2: error: ld returned 1 exit status

在gcc编译.c文件之后需要加参数,-l libmyc.a,且需要去掉lib和.a,因此正确的命令是gcc main.c -lmyc (-l后面可以加空格也可以不加空格) 

[jkl@host roommate]$ gcc main.c -lmyc
[jkl@host roommate]$ ls
a.out  main.c  mylib
[jkl@host roommate]$ ./a.out
10 + 20  = 30
[jkl@host roommate]$ ls
a.out  log.txt  main.c  mylib
[jkl@host roommate]$ cat log.txt
这是我写的...

 第二种方式不推荐,因此演示完之后最好将拷贝的文件给删除掉。

[jkl@host roommate]$ sudo rm /usr/include/mymath.h
[jkl@host roommate]$ sudo rm /usr/include/mystdio.h
[jkl@host roommate]$ sudo rm /usr/lib64/libmyc.a
[jkl@host roommate]$ ls /usr/include/mymath.h
ls: cannot access /usr/include/mymath.h: No such file or directory
[jkl@host roommate]$ ls /usr/include/mystdio.h
ls: cannot access /usr/include/mystdio.h: No such file or directory
[jkl@host roommate]$ ls /usr/lib64/libmyc.a
ls: cannot access /usr/lib64/libmyc.a: No such file or directory

 方式三:通过命令链接静态库

[jkl@host roommate]$ tree .
.
|-- main.c
`-- mylib|-- include|   |-- mymath.h|   `-- mystdio.h`-- lib`-- libmyc.a3 directories, 4 files

为什么不能直接使用 gcc main.c myc.a?

 因为告诉了gcc/g++编译器,但是没有告诉操作系统!!!

使用静态库:在编译其他程序时,可以通过-I(指定用户自定义头文件搜索路径)  -L(指定用户自定义库文件搜索路径)和 -l(执行确定的第三方库名称,去掉前缀lib和后缀.a)选项来链接静态库

[jkl@host roommate]$ gcc main.c -I ./mylib/include/ -L ./mylib/lib -lmyc
[jkl@host roommate]$ ls
a.out  main.c  mylib
[jkl@host roommate]$ ./a.out
10 + 20  = 30
[jkl@host roommate]$ ls
a.out  log.txt  main.c  mylib
[jkl@host roommate]$ cat log.txt
这是我写的...

上面是动态链接的

[jkl@host roommate]$ ldd a.outlinux-vdso.so.1 =>  (0x00007ffef6bf9000)libc.so.6 => /lib64/libc.so.6 (0x00007f0448055000)/lib64/ld-linux-x86-64.so.2 (0x00007f0448423000)

 gcc在不使用static选项的时候,并且只提供.a,只能静态链接当前的.a库,其他库正常动态链接,因此ldd能够查看动态库。

想要静态链接得加 -static

[jkl@host roommate]$ gcc main.c -I ./mylib/include/ -L ./mylib/lib -lmyc -static
[jkl@host roommate]$ ls
a.out  log.txt  main.c  mylib
[jkl@host roommate]$ ldd a.outnot a dynamic executable
[jkl@host roommate]$ file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=b10e09a9d03b05ebc14934c15a9d8b7071c94c29, not stripped

-static的意义是什么?

必须强制添加,因为将我们的程序进行静态链接,这要求我们链接的任何库都必须提供对应的静态库版本。

http://www.rdtb.cn/news/19356.html

相关文章:

  • 获取整个网站源码工具凡科建站登录入口
  • 常州本地招聘网站网页制作的软件有哪些
  • 网站维护中页面设计网站搜索引擎优化主要方法
  • 赵县网站建设百度管理员联系方式
  • 网站中上传资料存放ftp上海整站seo
  • 重庆网站建设设计公司信息找谁做百度关键词排名
  • 教你如何用天翼云盘做网站热搜排行榜今日排名
  • 做网站技术方法有东莞网站建设排名
  • 跨境电商自建站是什么成都百度推广开户公司
  • 做ppt用什么网站推广策划书模板范文
  • 境外网站服务器冯耀宗seo视频教程
  • 做阿里云网站百度咨询
  • 杭州 平台 公司 网站建设系统优化的意义
  • wordpress jenn 主题seo网站推广费用
  • 广州有几个区 分别叫什么简述seo的概念
  • 架设多个web网站有哪些方法百度推广没有一点效果
  • 怎么给公司网站上放视频人力资源培训机构
  • 网站设计是做什么的seo排名外包
  • 三水住房和城乡建设局的网站北京百度公司总部电话
  • 企业网站手机版模板免费下载进入百度知道首页
  • 顺德网站建设哪家好青岛网站推广公司
  • 成立网站要营业执照吗搜索广告是什么意思
  • 网站如何做绿标百度账户托管运营
  • 产品开发的流程和步骤抖音seo关键词优化排名
  • 合肥网站建设哪里好新闻最新热点
  • 武汉设计网站建设网页seo搜索引擎优化
  • 做网站在哪里申请推介网
  • 宁夏网站建设怎么样沈阳专业网站seo推广
  • 奉贤做网站制作搜索指数在线查询
  • 点击颜色更换网站主题2022年seo最新优化策略