Windows的静态库与动态库

Windows静态库与动态库 1.静态库 1.1 静态库特点

运行不存在

静态库源码被链接到调用程序中

目标程序的归档

1.2 C语言静态库

C静态库的创建

创建一个静态库项目。

添加库程序,源文件使用C文件。

int Clib_add(int add1,int add2){ return add1+add2; } int Clib_sub(int sub1,int sub2){ return sub1 - sub2; }

C静态库的使用

库路劲设置:可以使用pragma关键字设置

pragma comment(lib,"../lib/clib.lib")

#pragma comment(lib,"../Debug/Clib.lib") #include <stdio.h> #include <process.h> int main(){ int sum,sub; sum = Clib_add(5,3); sub = Clib_sub(5,3); printf("sum=%d,sub=%d\n",sum,sub); system("pause"); return 0; } 1.3 C++语言静态库

C++静态库的创建

创建一个静态库项目

添加库程序,源文件使用cpp文件

int CPPlib_add(int add1,int add2){ return add1 + add2; } int CPPlib_sub(int sub1,int sub2){ return sub1 - sub2; }

C++静态库的使用

库路径设置:可以使用pragma关键字设置

pragma comment(lib,"../lib/cpplib.lib")

#include <iostream> using namespace std; //给链接器看 int CPPlib_add(int add1,int add2); int CPPlib_sub(int sub1,int sub2); //给编译器看 #pragma comment(lib,"../Debug/CPPlib.lib") //?CPPlib_add@@YAHHH@Z / ?CPPlib_sub@@YAHHH@Z extern "C" int Clib_add(int add1,int add2); extern "C" int Clib_sub(int sub1,int sub2); #pragma comment(lib,"../Debug/Clib.lib") //Clib_add / Clib_sub int main(){ //调c++库函数 int sum = CPPlib_add(5,4); //?CPPlib_add@@YAHHH@Z int sub = CPPlib_sub(5,4); //?CPPlib_sub@@YAHHH@Z cout << "sum=" << sum << ",sub=" << sub << endl; //调c库函数 sum = Clib_add(5,3); //?Clib_add@@YAHHH@Z 使用extern "C",编译时不换函数名-->Clib_add sub = Clib_sub(5,3); //?Clib_sub@@YAHHH@Z -->Clib_sub cout << "sum=" << sum << ",sub=" << sub << endl; system("pause"); return 0; } 2.动态库 2.1 动态库特点

动态库的特点

运行时独立存在

源码不会链接到执行程序

使用时加载(使用动态库必须使动态库执行)

与静态库的比较

由于静态库是将代码嵌入到使用程序中,多个程序使用时,会有多分代码,所以代码体积会增大。动态库的代码只需要存在一份,其他程序通过函数地址使用,所以代码体积小。

静态库发生变化后,新的代码需要重新链接嵌入到执行程序中。动态库发生变化后,如果库中函数的定义(或地址)未变化,其他使用DLL的程序不需要重新链接。

2.2动态库创建

创建动态库项目

添加库程序

库程序导出 - 提供给使用者库中的函数等信息。

声明导出:使用_declspec(dllexport)导出函数

注意:动态库编译链接后,也会有LIB文件,是作为动态库函数映射使用,与静态库不完全相同。

制作动态库

_declspec(dllexport) int CPPdll_add(int add1,int add2){ return add1 + add2; } _declspec(dllexport) int CPPdll_sub(int sub1,int sub2){ return sub1 - sub2; } _declspec(dllexport) int CPPdll_mul(int mul1,int mul2){ return mul1 * mul2; }

动态库原理图

模块定义文件:.def

例如:LIBRARY DLLFunc //库

​ EXPORTS //库导出表

​ DLL_Mul @1 //导出的函数

不加声明导出

int CPPdll_add(int add1,int add2){ return add1 + add2; } int CPPdll_sub(int sub1,int sub2){ return sub1 - sub2; } int CPPdll_mul(int mul1,int mul2){ return mul1 * mul2; }

添加模块定义导出文件

LIBRARY CPPDll EXPORTS CPPdll_add @1 CPPdll_sub @2 CPPdll_mul @3

2.3动态库的使用

隐式链接(操作系统负责使动态库执行)

头文件和函数原型

​ 可以在函数原型的声明前,增加_declspec(dllimport)

导入动态库的LIB文件

在程序中使用函数

隐式链接的情况,dll文件可以存放的路径:

与执行文件中同一个目录下(建议放在此目录下)

当前工作目录

Windows目录

Windows/System32目录

Windows/System

环境变量PATH指定目录

#include <iostream> using namespace std; _declspec(dllimport)int CPPdll_add(int add1,int add2); _declspec(dllimport)int CPPdll_sub(int sub1,int sub2); _declspec(dllimport)int CPPdll_mul(int mul1,int mul2); //通知链接器到哪抓编号和dll文件名(CPPDll.dll) #pragma comment(lib,"../Debug/CPPDll.lib") int main(){ int sum = CPPdll_add(5,4); int sub = CPPdll_sub(5,4); int mul = CPPdll_mul(5,4); cout << "sum=" << sum << ",sub=" << sub << ",mul=" << mul << endl; system("pause"); return 0; }

显示链接(程序员自己负责使动态库执行)

定义函数指针类型 typedef

加载动态库

HMODULE LoadLibrary( LPCTSTR lpFileName //动态库文件名或全路劲 ); //返回DLL的实例句柄(HINSTANCE)

获取函数地址

FARPROC GetProcAddress( HMODULE hModule //DLL句柄 LPCSTR lpProcName //函数名称 ); //成功返回函数地址

使用函数

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwfgwp.html