C++windows内核编程笔记day11 win32静态库和动态库的使用

简介: windows库程序:静态库: 源代码被链接到调用的程序或动态库,被调用时,代码最少有1份,文件后缀.LIB 动态库: 函数被程序或其他动态库调用,被调用时,代码只有1份,文件后缀.
windows库程序:

静态库:

源代码被链接到调用的程序或动态库,被调用时,代码最少有1份,文件后缀.LIB

动态库: 函数被程序或其他动态库调用,被调用时,代码只有1份,文件后缀.DLL


静态库(C语言):
创建时,选择文本类型文件,输入Clib.c,设置输出路径 ../lib/Clib.lib


int Clib_add(int a,int b)
{
return a+b;
}
同一上工作区,建立控制台程序(.c文件)调用静态库:
#include<STDIO.H>
#pragma comment(lib,"../lib/Clib.lib") //包含静态库文件
//可以在 工程-设置-连接-对象/库模块 中加入静态库相对地址 ../lib/Clib.lib
int main()
{
int sum=Clib_add(12,34);
printf("12+34 结果是:%d\n",sum);
return 0;
}


C++程序调用C++静态库,与C中大部分一样,但调用之前,要写函数声明。

C++程序调用C静态库,写函数声明时,前面加 extern "C".

使用静态库示例:

新建 win32 static library工程(Clib):

新建一个文件,Clib.c,代码:

int Clib_add(int a,int b)
{
	return a+b;
}
int Clib_sub(int a,int b)
{
	return a-b;
}

生成,产生一个 Clib.lib文件。

新建C控制台程序,使用静态库,代码:

#include<STDIO.H>
#pragma comment(lib,"../lib/Clib.lib") //包含静态库文件
//可以在 工程-设置-连接-对象/库模块 中加入静态库相对地址 ../lib/Clib.lib
int main()
{
	int sum=Clib_add(12,34);
	printf("12+34 结果是:%d\n",sum);
	return 0;
}


动态库:

(项目:Cdll):
在函数前加 _declspec(dllexport),声明方式导出动态库函数地址到.lib。
生成的.dll和.lib(.lib要手动复制到lib文件夹)。


C程序调用:
#pragma comment(lib,"../lib/Cdll.lib")//函数地址文件
//在运行时,Cdll.dll文件要放在与程序同一目录中或系统PATH目录中
//(隐式链接动态库dll)




C++程序调用C++动态库,与C中大部分一样,但调用之前,要写函数声明。
C++程序调用C动态库,写函数声明时,前面加 extern "C".


显式链接dll的方法(不使用lib文件,要建立.def文件):
1.定义函数指针类型
2.加载动态库
3.获取函数地址
4.使用函数
5.卸载动态库
.def文件格式:
LIBRARY CPPdll
EXPORTS
  CPPdll_add @1
  CPPdll_sub @2
  CPPdll_multi @3
示例:

新建动态库Cdll项目,win32 Dynamic-link library

新建一个Cdll.c文件,内容:

_declspec(dllexport) int Cdll_add(int a,int b)
{
	return a+b;
}

新建一个c控制台程序,使用动态库,内容:

#include <STDIO.H>
#pragma comment(lib,"../lib/Cdll.lib")//函数地址文件
//.dll文件要放在与程序同一目录中
int main()
{
	int sum=Cdll_add(34,56);
	printf("34+56=%d\n",sum);
	return 0;
}


C++中使用示例:

//CPPdll项目中:

//CPPdll.cpp

_declspec(dllexport) int CPPdll_add(int a,int b)
{
	return a+b;
}

//CPPdll.def

LIBRARY CPPdll
EXPORTS
  CPPdll_add @1

编译生成dll和lib,

新建测试项目调用CPPdll和Cdll

#include<STDIO.H>
#pragma comment(lib,"../lib/CPPdll.lib")//C++调用c++的动态库
#pragma comment(lib,"../lib/Cdll.lib")//c++调用c的动态库
extern "C" _declspec(dllexport)  int Cdll_add(int a,int b);
_declspec(dllexport) int CPPdll_add(int a,int b);
int main()
{
	int sum=CPPdll_add(23,45);
	printf("23+45=%d\n",sum);
 	int sum2=Cdll_add(231,45);
 	printf("231+45=%d\n",sum2);
	return 0;
}

附:显示调用CPPdll

#include <STDIO.H>
#include <WINDOWS.H>
//动态库加.def 文件申明函数地址
typedef int(*DLL_ADD)(int a,int b);//函数类型
int main()
{
HINSTANCE dll= LoadLibrary("CPPdll.dll");//加载动态库
DLL_ADD add=(DLL_ADD)GetProcAddress(dll,"CPPdll_add");
int sum=add(23,45);
printf("23+45=%d\n",sum);
FreeLibrary(dll);
return 0;
}



动态库中的类定义:
//dllclass.h文件,可以公开给调用方
#ifndef DLLCLASS_H
#define DLLCLASS_H
#ifdef DLLCLASS_EXPORTS     //在动态库.cpp中要定义,来表示导出
#define EXT_CLASS _declspec(dllexport) //cpp文件使用,导出
#else
#define EXT_CLASS _declspec(dllimport) //别人调用,导入
#endif
class EXT_CLASS CMath
{
public:
int add(int a,int b);
};
#endif


//dllclass.cpp文件
#define DLLCLASS_EXPORTS
#include <WINDOWS.H>
#include <STDIO.H>
#include "dllclass.h"
//动态库入口函数,返回false则表示调用不成功
BOOL CALLBACK DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH://进程加载,初始化
{
printf("loading dll ……\n");
}
break;
case DLL_PROCESS_DETACH://进程卸载,清理资源
{
printf("unloading dll ……\n");
}
break;
}
return true;
}
int CMath::add(int a,int b)
{
return a+b;
}


//调用
#include "../dllclass/dllclass.h"//包含类声明文件
#pragma comment(lib,"../lib/dllclass.lib") //包含静态库文件

int main()

{
CMath math;
int sum3=math.add(3,4);
cout<<"3+4 结果是:"<<sum3<<endl;

return 0;

}




相关文章
|
存储 算法 C++
Windows共享文件:探秘C++实现的B树索引算法奇境
在数字化时代,Windows共享文件的高效管理至关重要。B树算法以其自平衡多路搜索特性,在文件索引与存储优化中表现出色。本文探讨B树在Windows共享文件中的应用,通过C++实现具体代码,展示其构建文件索引、优化数据存储的能力,提升文件检索效率。B树通过减少磁盘I/O操作,确保查询高效,为企业和个人提供流畅的文件共享体验。
|
11月前
|
Ubuntu API C++
C++标准库、Windows API及Ubuntu API的综合应用
总之,C++标准库、Windows API和Ubuntu API的综合应用是一项挑战性较大的任务,需要开发者具备跨平台编程的深入知识和丰富经验。通过合理的架构设计和有效的工具选择,可以在不同的操作系统平台上高效地开发和部署应用程序。
386 11
|
安全 程序员 编译器
【实战经验】17个C++编程常见错误及其解决方案
想必不少程序员都有类似的经历:辛苦敲完项目代码,内心满是对作品品质的自信,然而当静态扫描工具登场时,却揭示出诸多隐藏的警告问题。为了让自己的编程之路更加顺畅,也为了持续精进技艺,我想借此机会汇总分享那些常被我们无意间忽视却又导致警告的编程小细节,以此作为对未来的自我警示和提升。
1824 126
|
存储 C++ UED
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展
本文介绍了如何通过四步实现C++插件化编程,实现功能定制与扩展。主要内容包括引言、概述、需求分析、设计方案、详细设计、验证和总结。通过动态加载功能模块,实现软件的高度灵活性和可扩展性,支持快速定制和市场变化响应。具体步骤涉及配置文件构建、模块编译、动态库入口实现和主程序加载。验证部分展示了模块加载成功的日志和配置信息。总结中强调了插件化编程的优势及其在多个方面的应用。
1615 172
|
存储 缓存 C++
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
1096 1
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
|
存储 机器学习/深度学习 编译器
【C++终极篇】C++11:编程新纪元的神秘力量揭秘
【C++终极篇】C++11:编程新纪元的神秘力量揭秘
|
存储 算法 C++
深入浅出 C++ STL:解锁高效编程的秘密武器
C++ 标准模板库(STL)是现代 C++ 的核心部分之一,为开发者提供了丰富的预定义数据结构和算法,极大地提升了编程效率和代码的可读性。理解和掌握 STL 对于 C++ 开发者来说至关重要。以下是对 STL 的详细介绍,涵盖其基础知识、发展历史、核心组件、重要性和学习方法。
|
存储 安全 算法
深入理解C++模板编程:从基础到进阶
在C++编程中,模板是实现泛型编程的关键工具。模板使得代码能够适用于不同的数据类型,极大地提升了代码复用性、灵活性和可维护性。本文将深入探讨模板编程的基础知识,包括函数模板和类模板的定义、使用、以及它们的实例化和匹配规则。
|
消息中间件 存储 安全
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
359 0
C++入门6——模板(泛型编程、函数模板、类模板)