C语言程序静态库和动态库的创建及其应用
静态库和动态库编译

静态库和动态库编译静态库和动态库是编程中常用的两种库文件形式,本文将介绍它们的编译过程和使用方法。
1. 静态库编译静态库是一种在编译时被链接到程序中的库文件,它包含了程序所依赖的所有函数和数据结构,因此程序在运行时不需要再加载库文件。
静态库的编译过程包括以下步骤:(1)创建一个或多个源文件,使用编译器将它们编译成目标文件(.o 或 .obj)。
(2)将多个目标文件打包成一个静态库文件,通常使用 ar 工具完成此操作。
例如,在 Linux 系统下,可以使用以下命令创建名为 libfoo.a 的静态库文件:$ ar rcs libfoo.a foo1.o foo2.o ...其中,rcs 参数分别表示创建、向库文件中添加目标文件和生成索引表。
(3)在编译器中使用静态库,需要将其链接到目标程序中。
在Linux 系统下,可以使用以下命令编译名为 main.c 的源文件和名为libfoo.a 的静态库文件:$ gcc -o main main.c -L. -lfoo其中,-L 参数指定库文件搜索路径,. 表示当前目录;-l 参数指定链接库文件,实际上是将其前缀 lib 和后缀 .a 去掉,即 foo。
2. 动态库编译动态库是一种在程序运行时动态加载的库文件,它只包含程序所需要的部分函数和数据结构,因此可以减小程序的尺寸和加载时间。
动态库的编译过程包括以下步骤:(1)创建一个或多个源文件,使用编译器将它们编译成目标文件。
(2)将多个目标文件打包成一个共享库文件,通常使用 ld 或链接器完成此操作。
例如,在 Linux 系统下,可以使用以下命令创建名为 libfoo.so 的动态库文件:$ gcc -shared -o libfoo.so foo1.o foo2.o ...其中,-shared 参数表示生成共享库文件。
(3)在编译器中使用动态库,需要将其链接到目标程序中。
在Linux 系统下,可以使用以下命令编译名为 main.c 的源文件和名为libfoo.so 的动态库文件:$ gcc -o main main.c -L. -lfoo其中,-L 和 -l 参数的含义同静态库。
C语言编写静态链接库及其使用

C语⾔编写静态链接库及其使⽤本篇讲述使⽤C语⾔编写静态链接库,⽽且使⽤C和C++的⽅式来调⽤等.⼀、静态库程序:执⾏时不独⽴存在,链接到可执⾏⽂件或者动态库中,⽬标程序的归档。
1、⽤C编写静态库步骤a.建⽴项⽬(Win32 Static Library)b.加⼊库程序,源⽂件使⽤C⽂件(Win32 Static Library)clib.c库源⽂件<pre name="code" class="cpp">int CLib_add(int add1,int add2){return add1+add2;}int CLib_sub(int add1,int add2){return add1-add2;}编译,链接后产⽣clib.lib,后⾯使⽤这个⽂件2、静态库的使⽤a.建⽴⼀个C⽂件,能够在⽂件⾥直接使⽤C库函数,不须要头⽂件,C编译器仅仅是依据库函数名称,在库中找到相应的函数代码,进⾏链接。
b.库的路径设置。
项⽬的“Setting”中设置库路径,也能够使⽤#pragmakeyword设置 #pragma comment(lib,"..\\clib\\clib.lib")3、C的⽅式调⽤C语⾔编写的静态库C Type//C编译器什么头⽂件及函数声明都不要.....#pragma comment(lib,"..\\clib\\clib.lib") //通知链接器。
到那找源码.int main(void){int num1 = 100;int num2 = 1000;int nSum = CLib_add(num1,num2);int nSub = CLib_sub(num1,num2);printf("nSum = %d,nSub = %d\r\n",nSum,nSub);return 0;}</pre><pre name="code" class="cpp">4、<strong>C++的⽅式调⽤C语⾔编写的静态库</strong>在CPP环境使⽤C静态库。
第三阶段学习总结,静态库和动态库的创建和使用C 篇

利用以上代码和文件创建动态库: g++ -fpic -shared -o libmyfun.so fun1.o fun2.o fun3.o 其中: -fpic 使输出的对象模块是按照可重定位地址方式生成的。 -shared 指定把对应的源文件生成对应的动态链接库文件 libmyfun.so 文件。下面看一下如何 使用对应的动态链接库。 g++ -o somyfuntest main.cpp -L . -lmyfun 与静态库的利用不同的是,在默认情况下,当程序运行时,系统会搜索/lib 和/usr./lib 库,如果连接库没有存在这两个目录下,系统将不能找到链接库,程序会终止运行。所以, 一般情况下我们需要手动的添加路径或者更改 LD_LIBRARY_PATH 的环境变量。 前者,我们需要把当前生成的动态库的路径加到/usr/local/lib 下面。我一般情况下习惯 于用后一种方法,我习惯于这样做,export LD_LIBRARY_PATH=$PWD,然后我们就可 以执行可执行文件 somyfuntest 了。 库函数就简单介绍到这里,想了解更深尚需时日。“冰冻三尺非一日之寒”,对嵌入式的 学习非一朝一日所能完成的,短短的几个月,时间之紧迫,内容之丰盛,尚需多反馈总结啊!
#include"head.h" int main() { fun1(); fun2(); fun3();
return 0; }
利用以上的代码和文件创建静态库:
利用 G++生成对应目标文件: g++ –c fun1.c fun2.c fun3.c 如果对应的文件没有错误,g++会对文件进行编译生成 fun1.o、fun2.o 和 fun3.o 三个目标 文件(相当于 windows 下的 obj 文件)。然后用 ar 创建一个名字为 libstr.a 的库文件,并把 fun1.o、fun2.o 和 fun3.o 内容插入到对应的库文件中。
静态库的使用与创建

静态库的使用与创建静态库是一种预编译的库,它包含了一组已经编译好的目标文件(.o文件)。
使用静态库可以将一些常用的函数、类或其他代码打包成一个单独的文件,以便在多个应用程序中重复使用。
使用静态库:1. 创建静态库:首先需要将要打包的源代码编译成目标文件,然后使用静态库工具(如ar)将目标文件打包成静态库文件(.a文件)。
2. 链接静态库:在编译应用程序时,需要引用静态库文件,并将其链接到应用程序的可执行文件中。
可以使用编译器的命令行选项来指定链接静态库的路径和名称。
创建静态库的一般步骤如下:1. 编写源代码文件:创建需要打包进静态库的源代码文件(.c、.cpp、.h等)。
2. 编译源代码文件:使用编译器将源代码文件编译成目标文件(.o文件)。
例如,使用gcc编译C文件:`gcc -c file.c -o file.o`。
3. 打包目标文件:使用静态库工具(如ar)将目标文件打包成静态库文件。
例如,使用ar工具创建静态库:`ar rcs libfile.a file1.o file2.o ...`。
4. 链接静态库:在应用程序的编译过程中,使用编译器的命令行选项来链接静态库文件。
例如,使用gcc链接静态库:`gcc main.c -o main -L<path_to_lib> -lfile`。
注意事项:在创建静态库时,需要保持相应源代码文件的可移植性和独立性,以便在不同的项目中使用。
链接静态库时,需要确保目标文件和静态库文件的路径正确,并且编译器能够找到它们。
如果静态库依赖于其他库,需要确保这些依赖库也正确链接到应用程序中。
使用静态库可以提高代码的重用性和管理性,尤其是对于一些通用的函数或模块。
这种方法适用于部署到嵌入式设备、静态链接的可执行文件等场景。
Linux环境下c语言静态链接库和动态链接库创建和使用

库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。
面对比一下两者:静态链接库:当要使用时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。
动态库而言:某个程序在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。
如果有,则让其共享那一个拷贝;只有没有才链接载入。
在程序运行的时候,被调用的动态链接库函数被安置在内存的某个地方,所有调用它的程序将指向这个代码段。
因此,这些代码必须使用相对地址,而不是绝对地址。
在编译的时候,我们需要告诉编译器,这些对象文件是用来做动态链接库的,所以要用地址不无关代码(Position Independent Code (PIC))。
注意:linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。
一.静态库下面就通过实际的例子来向大家演示一下,该怎样编译和使用静态和动态链接库:1. 编辑测试文件二个文件:add.c、sub.c、add.h 、sub.h 和main.c/*add.h */#ifndef _ADD_H_#define _ADD_H_int add(int a, int b);#endif-------------------------------------------------------------------------------------------------/*add.c*/#include "add.h"int add(int a, int b){return a+b;}------------------------------------------------------------------------------------------------- /*sub.h*/#ifndef _SUB_H_#define _SUB_H_int sub(int a, int b);#endif------------------------------------------------------------------------------------------------- /*sub.c*/#include "add.h"int sub(int a, int b){return a-b;}------------------------------------------------------------------------------------------------- /*main.c*/#include <stdio.h>#include "add.h"#include "sub.h"int main(void){printf("1 + 2 = %d\n", add(1, 2));printf("1 - 2 = %d\n", sub(1, 2));return 0;}------------------------------------------------------------------------------------------------- 2.将add.c 和sub.c 编译生成.o文件gcc -c add.cgcc -c sub.c生成的文件:sub.o ,add.o无论是静态库文件还是动态库文件,都是由.o 文件创建的。
C静态库(lib)及动态库(dll)的创建及调用

C静态库(lib)及动态库(dll)的创建及调用一、静态库的创建及调用最近在编程序的时候,用到静态库和动态库的创建和调用,将自己的一些心得总结如下,希望对各位有所帮助,有不恰当之处欢迎评论留言。
静态库和动态库的区别可以参考博客:windows中静态库lib和动态dll的区别及使用方法_dxzysk的专栏-CSDN博客_动态dll和静态库的区别1、静态库的创建为了方便大家学习,从空项目进行演示,实现输入两个数求出两数之和及两数之差,本文使用VS2017编译器。
(1)创建空项目(2)新建头文件.h和源文件.cpp其中test工程为后面测试用工程,现在不用考虑。
(3)修改项目属性,将目标文件扩展名和配置类型均修改为.lib (4)在项目头文件testLib.h中编写代码方法一和方法二均可以生成和调用(5)源文件testLib.cpp代码编写(6)工程生成可以看到工程目录下生成了testLib.ib和testLib.pdb文件,代表静态库生成成功。
2、静态库的调用(1)为了方便演示,在静态库生成的同解决方案下创建测试工程test,本地创建的是控制台应用程序。
(2)创建完测试工程后,在test.cpp文件中编写静态库调用程序(3)将test工程设置为启动工程,编译运行,会出现报错(4)针对(3)出现的报错,需要在项目中引入静态库文件路径静态库生成工程和测试工程目录如下:引入静态库的相对路径再次编译就可以成功。
运行结果如下至此,静态库的创建及调用讲解结束。
二、动态库的创建及调用1、动态库的创建动态库的创建介绍两种方式:__declspec(dllexport)和.def文件导出。
1.1、动态库的创建(__declspec(dllexport))(1)同静态库一样创建空项目testDll,创建头文件和源文件(2)修改项目属性,将目标文件扩展名和配置类型均修改为.dll(3)修改项目头文件testDll.h,本文介绍三种dll库生成的方法动态生成库的关键字为__declspec(dllexport)方法一和方法二的区别就是标识符是否被定义,如果标识符TESTDLL被定义则重新定义标识符TESTDLLAPI,并使用重新定义的标识符进行函数导出;如果标识符TESTDLL未被定义,则使用当前定义的标识符进行函数导出。
GCC编译步骤及静态库动态库制作

GCC编译步骤及静态库动态库制作GCC是一种广泛使用的编译器,可以将C、C++等高级语言源代码转换为可执行的机器码。
本文将介绍GCC编译步骤及制作静态库和动态库的过程。
1. 预处理(Preprocessing):预处理器会处理源代码,根据预编译指令进行操作,例如宏展开、条件编译等。
预处理后的代码仍然是源代码,只是进行了一些文本替换和宏展开操作。
3. 汇编(Assembling):汇编器将汇编语言转换为机器码,生成目标文件(Object Files)。
目标文件包含可执行代码的二进制表示,以及与其他目标文件和库文件链接的信息。
4. 链接(Linking):链接器将多个目标文件和库文件结合在一起,生成最终的可执行文件。
链接器会解析目标文件之间的引用和符号,将它们关联起来,并生成可执行文件。
静态库制作:静态库是一种包含可执行代码和函数的库文件,在链接时会将库文件中的代码复制到最终的可执行文件中。
静态库的制作分为以下几个步骤:1.编写库代码:创建一个或多个源文件,其中包含一些可重用的函数和类。
确保将库代码编写成独立的、可移植的模块。
2. 编译库代码:使用GCC进行编译,将源代码文件编译成目标文件。
例如,对于C文件使用以下命令编译为目标文件:`gcc -c file1.cfile2.c`。
3. 归档库文件:将目标文件归档成库文件。
使用GCC进行归档时,可以使用`ar`命令。
例如,使用以下命令将目标文件归档:`ar rcs libmylib.a file1.o file2.o`。
这将创建名为libmylib.a的静态库文件。
4. 使用库文件:在需要使用库函数的程序中,包含库的头文件,并在链接时将库文件链接到程序中。
例如,使用以下命令编译和链接程序:`gcc -o myprog myprog.c -L. -lmylib`。
其中,-L参数指定库文件的路径,-l参数指定要链接的库文件。
在程序中使用库函数时,只需包含相应的头文件,并调用库函数。
GCC生成静态库.o以及动态库.so文件及其使用学习

GCC⽣成静态库.o以及动态库.so⽂件及其使⽤学习⽬录编译⽣成静态库⽂件1.编辑⽣成例⼦程序hello.h,hello.c,main.chello.c是函数库的源程序,其中包括公⽤函数hello,该函数将在屏幕上输出(hello XXX)hello.h为该函数库的头⽂件,main.c为测试库的主程序。
在主程序中调⽤函数hello程序1:hello.h#ifndef HELLO_H#define HELLO_Hvoid hello(const char*name)#endif//HELLO_H程序2 :hello.c#include<stdio.h>void hello(const char *name){printf("Hello %s!\n",name);}程序3 :main.c#include "hello.h"int main(){hello("everyone");return 0;}2,将hello.c编译成.o⽂件⽆论是静态库还是动态库都是由.o⽂件创建的。
因此,我们必须将源程序hello.c通过gcc先编译成.o⽂件输⼊命令 gcc -c hello.c在⽂件夹中发现⽣成了hello.o⽂件3.由.o⽂件创建静态库静态库⽂件名命名规范是以lib为前缀紧接着跟着静态库名,扩展名为.a。
例如:我们将创建的⽽静态库命名为myhello,则静态库⽂件名就是libmyhello.a。
在创建和使⽤静态库时我们需要注意这点,创建静态库⽤ar命令。
在系统提⽰符下输⼊以下命令创建静态库⽂件libmyhello.a#ar -crv libmyhello.a hello.o4.在程序中使⽤静态库静态库制作完了如何使⽤它内部的函数呢?只需要在使⽤到这些公⽤函数的源程序中包含这些公⽤函数的原型声明,然后再gcc命令⽣成⽬标⽂件时指明静态库名字,gcc将会从静态库中将公⽤函数连接到⽬标⽂件中注意gcc会在静态库名前加上前缀lib,然后追加.a得到的静态库⽂件名来查找静态库⽂件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C语言程序静态库和动态库的创建及其应用
在用c写程序时,很多时候需要存储一些简单的数据,如果为此而用mysql数据库就有些大才小用了,可以把这些数据以结构的形写入文件,然后再需要时读取文件,取出数据。
如下是定义函数的源文件和头文件:
源文件struct.c:
#include "struct.h"
//第一个参数是要写入的文件名,第二个参数是缓冲区,第三个参数是缓冲区大小,第四个参数是打开文件流的形态,返回TRUE表示写入成功,返回FALSE表示写入失败int writeStruct(const char *fileName,char *buffer,int bufferLen,char *mode){ int ret;
FILE *fileID = NULL;
fileID = fopen(fileName,mode);
if (fileID == NULL){
perror("fopen");
goto writeEnd;
}
rewind(fileID);
ret = fwrite(buffer,bufferLen,1,fileID);
if (ret <= 0){
perror("fwrite");
goto writeEnd;
}
if (fileID != NULL){
fclose(fileID);
fileID = NULL;
}
return TRUE;
writeEnd:
if (fileID != NULL){
fclose(fileID);
fileID = NULL;
}
return FALSE;
}
//第一个参数是要读取的文件名,第二个参数是缓冲区,第三个参数是缓冲区大小,第四个参数是打开文件流的形态,返回TRUE表示读取成功,返回FALSE表示读取失败int readStruct(const char *fileName,char *buffer,int bufferLen,char *mode){ int ret;
FILE *fileID = NULL;
fileID = fopen(fileName,mode);
if (fileID == NULL){
perror("fopen");
goto readEnd;
}
rewind(fileID);
memset(buffer,0,sizeof(buffer));
ret = fread(buffer,bufferLen,1,fileID);
if (ret >= 0){
strcat(buffer,"\0");
}else{
perror("fread") ;
goto readEnd;
}
if (fileID != NULL){
fclose(fileID);
fileID = NULL;
}
return TRUE;
readEnd:
if (fileID != NULL){
fclose(fileID);
fileID = NULL;
}
return FALSE;
}
头文件struct.h:
#ifndef OWNSTRUCT_H_
#define OWNSTRUCT_H_
#include
#include
#include
#define FALSE 0
#define TRUE 1
//第一个参数是要写入的文件名,第二个参数是缓冲区,第三个参数是缓冲区大小,第四个参数是打开文件流的形态,返回TRUE表示写入成功,返回FALSE表示写入失败int writeStruct(const char *fileName,char *buffer,int bufferLen,char *mode);
//第一个参数是要读取的文件名,第二个参数是缓冲区,第三个参数是缓冲区大小,第四个参数是打开文件流的形态,返回TRUE表示读取成功,返回FALSE表示读取失败int readStruct(const char *fileName,char *buffer,int bufferLen,char *mode);
#endif
为了使用方便,可以把这两个函数接口定义为动态链接库或静态链接库。
用动态链接库编译生成的可执行文件需调用.so文件方可正常运行,灵活但稍显麻烦;用静态链接库编译生成的可执行文件可直接运行,不用再调用如.so般的依赖库文件,简单但不灵活。
静态链接库:
1、编译生成目标文件
gcc -c struct.c
2、创建静态库
ar cqs libstruct.a struct.o (顺序不能乱)
3、链接静态链接库,生成可执行文件
gcc main.c -static -L. -ltest -o main
动态链接库:
1、编译成动态链接库
gcc struct.c -fPIC -shared -o libstruct.so
2、链接动态链接库,生成可执行文件
gcc main.c -L. -lstruct -o main
3、设置库文件的环境路径
1)在bashrc或profile文件里用LD_LIBRARY_PATH定义,然后用source加载。
2)把库路径添加到ld.so.conf文件中,然后用ldconfig加载。
3)ldconfig /home/user/lib,仅能暂时性使用,若下次ldconfig时此目录下的动态链接库就不能被共享了。
gcc一些参数解析
-shared:指定生成动态链接库。
-static:指定生成静态链接库。
-fPIC:表示编译为位置独立的代码,用于编译共享库。
目标文件需要创建成位置无关码,概念上就是在可执行程序装载它们的时候,它们可以放在可执行程序的内存里的任何地方。
-L.:表示要连接的库在当前目录中。
-l:指定链接时需要的动态库。
编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称。
-Wall:生成所有警告信息。
-ggdb:此选项将尽可能的生成gdb的可以使用的调试信息。
-g:编译器在编译的时候产生调试信息。
-c:只激活预处理、编译和汇编,也就是把程序做成目标文件(.o文件)。
-Wl,options:把参数(options)传递给链接器ld。
如果options中间有逗号,就将options 分成多个选项,然后传递给链接程序。