包含testlib.lib和testlib.h两个文件,在写程序调用静态库里包含的函数的时候,编译完就已经把函数的实现放到了产生的exe文件里了,所以exe后期的运行不需要依赖静态库了,代价就是exe体积会变大。目前主流程序一般不用静态库。
包含testlib.lib(编译阶段需要)和testlib.dll(调用运行阶段会使用)两个文件,在写程序调用动态库里包含的函数的时候,编译阶段只把函数的重定位信息放到了exe文件里了,所以exe后期的运行需要依赖动态库。值得一提的是,虽然动态库和静态库都有一个.lib文件,但是两者完全不一样。动态库的.lib文件只在你调用的编译阶段需要,而.dll只在调用的运行阶段需要。
和Windows的动态库一样,命名如上。
Linux的静态库:LibXXX.a 编译库 Windows静态库├─static_lib.cpp
├─static_lib.h
├─pch.cpp #这两个是vc++自己产生的的预编译头,这里我们不关注
└─pch.h #这两个是vc++自己产生的的预编译头,这里我们不关注
#include "pch.h"
#include "static_lib.h"
int add(int x, int y)
{return x + y;
}
#pragma once
int add(int x, int y);
编译完成后得到DEBUG文件夹里得到static_lib.lib文件,另外加一个刚才用的static_lib.h,有这两个文件就可以调用函数add了,调用过程在后面。
Windows动态库├─dynamic_lib.cpp
├─dynamic_lib.h
├─pch.cpp #这两个是vc++自己产生的的预编译头,这里我们不关注
└─pch.h #这两个是vc++自己产生的的预编译头,这里我们不关注
#include "pch.h"
#include "dynamic_lib.h"
#define DLL_API _declspec(dllexport)
DLL_API int add(int a, int b) //实现两个整数相加
{return a + b;
}
#pragma once
#define DLL_API _declspec(dllexport)
int add(int x, int y);
编译完在DEBUG里会产生dynamic_lib.dll和dynamic_lib.lib两个文件
Linux静态库├─static_lib.c
└─static_lib.h
#include "static_lib.h"
int add(int a, int b)
{int c;
c = a + b;
return c ;
}
#pragma onece
int add(int a, int b);
编译过程分两步,先生成.o文件,然后根据.o文件归档为.a静态库文件
1、gcc -c static_lib.c
然后归档为静态库文件,这样就生成了静态库libstatic_lib.a
2、ar crv libstatic_lib.a static_lib.o
├─dynamic_lib.c
└─dynamic_lib.h
#include "dynamic_lib.h"
int add(int a, int b)
{int c;
c = a + b;
return c ;
}
#pragma onece
int add(int a, int b);
编译产生.so文件,命令行里输入
~$ gcc dynamic_lib.c -shared -fPIC -o libdynamic_lib.so
注意的是,一般产生的.so文件名要以lib开头
├─lib_test.cpp
└─stdafx.h #这是vc++自己产生的的预编译头,这里我们不关注
这里需要设置编译器,告诉编译器静态库叫什么名字,在哪个文件夹里。在VS里需要设置地方是项目—属性—VC++ 目录,将static_lib.h所在的路径C:\Users\john\Desktop\static_lib填到包含目录里,将之前生成的static_lib.lib所在路径C:\Users\john\Desktop\static_lib\DEBUG填到库目录里。然后在项目——属性—链接器—输入,将static_lib.lib输入到附加依赖项里(这一步其实等同于lib_test.cpp里的#pragma comment(lib, “static.lib”)这句话,两者二选一即可)。最后编译成功。
├─lib_test.cpp
└─stdafx.h #这是vc++自己产生的的预编译头,这里我们不关注
#include "stdafx.h"
#pragma comment(lib, "dynamic_lib.lib")
extern int add(int a, int b);
int _tmain(int argc, _TCHAR* argv[])
{int a = 0, b = 2, c;
c = add(a, b);
return 0;
}
注意,这里代码中少了一个include,多了一个extern了。在VS里需要设置地方是项目—属性—VC++目录,将之前生成的dynamic_lib.lib所在路径C:\Users\john\Desktop\dynamic_lib\DEBUG填到库目录里。然后在项目——属性—链接器—输入,将dynamic_lib.lib输入到附加依赖项里(这一步其实等同于lib_test.cpp里的#pragma comment(lib, “static.lib”)这句话,两者二选一即可)。最后编译成功。运行的时候需要把.dll文件放到生成exe的文件夹里,不然编译成功运行会出错
动态库的特点:Ꝏ动态库把对一些库函数的链接载入推迟到程序运行的时期。
Ꝏ可以实现进程之间的资源共享。(因此动态库也称为共享库)
Ꝏ将一些程序升级变得简单。
Ꝏ甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。
Window 与 Linux 执行文件格式不同,在创建动态库的时候有一些差异。
Ꝏ在 Windows 系统下的执行文件格式是 PE 格式,动态库需要一个 DllMain 函数做出初始化的入口,通常在导出函数的声明时需要有 _declspec(dllexport)关 键字。
ꝎLinux 下 gcc 编译的执行文件默认是 ELF 格式,不需要初始化入口,亦不需要函数做特别的声明,编写比较方便。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧