Win32编程之静态库编写与使用.动态链接库的编写与使用
Win32编程之静态库编写与使用.动态链接库的编写与使用
一丶什么是静态库.什么是动态链接库.
静态库其实就是解决模块开发的一种解决方案.在以前.我们写代码的时候.每个人都可以独立写一个项目.但是现在不行了.一个项目往往要很多人一起去编写.而其中用到的技术就类似于静态库.
每个人编写自己的东西.最后组合.
动态链接库.也称为Dll. 为什么有了静态库还要有动态链接库. 原因是静态库优缺点的.所以才出了动态链接库补充这个缺点.
缺点:
1.代码体积大. 使用静态库的程序编译出的体积很大.在汇编的层次中就是把静态库的代码跟可执行文件相链接了.
2.重复代码多.一个静态库可以有很多人编写.有得函数会有多次编写.
动态链接库就是解决上面缺点的.
二丶如何编写静态库以及如何使用.
1.创建静态库或者lib步骤
如果是VS系列编译器. 创建静态库的方法. VC++6.0 创建的时候是一个 static lib.... 因为笔者Vc6.0没有安装成功.(确实不支持了) 所以不再累赘
新建项目 -> VC++ ->win32项目 -> 静态库.
我们可以选择生成dll还是静态库.
2.编写静态lib库
如果我们创建了一个库文件.那么很简单. 添加一个.h文件. 填加一个实现文件.
也就是一个.h 一个.cpp
.h放我们的函数声明.
.cpp放我们的函数实现即可.
例如下图:
添加一个加法函数.
.h方声明. .cpp实现.
.h中的声明
int RetMyAddNumber(int a, int b);
.cpp的实现.
int RetMyAddNumber(int a,int b)
{
return a + b;
}
直接编译.然后寻找目录下我们编译好的静态lib库即可.
3.使用静态lib库
使用我们的静态lib库很简单.
1.需要.h文件. 也就是我们编写静态lib的声明文件.
2.需要编译好的静态lib.
3.我们的程序包含.h声明文件.并且再次使用宏命令包含静态lib.文件 #pragam comment(lib,"xxxx.lib");
这个是第一种方法.
第二种方法是放到目录中.并且VS配置库目录即可. 跟使用C语言的lib库是一样的.具体怎么配置不再累赘. 比较常用第一种.
三丶编写Dll并且使用DLL
生成我们的DLL跟上面是一样的.主不过选择DLL即可.
编写DLL 我们也需要有个头文件.跟一个实现文件.因为要给别人使用.
.h声明文件导出我们的Dll
1.第一种关键字导出方法.
extern "C" _declspec(dllexport) int _stdcall RetMyAddNumber(int a, int b); extern "C" _declspec(dllexport) int _stdcall RetMySubNumber(int a, int b);
.cpp实现文件
#include "MyDllHead.h" //必须包含.不包含则不会导出.
int RetMyAddNumber(int a, int b)
{
return a + b;
} int RetMySubNumber(int a, int b)
{
return a - b;
}
注意,因为我们的函数要给别人使用.所以必须要导出. 这里有两种方法. 第一种就是关键字导出. 第二种就是.def导出.
关键字导出:
_declspec(dllexeport) 函数返回值 函数调用约定 函数名称 (参数列表) 这样导出的函数带有名称粉碎.也就是说我们要使用的时候.函数名字已经变了.
所以另一个关键字 extern "C" 这个意思就是按照C语言函数定义给我们导出. 名称粉碎是因为C++有函数重载的概念.所以函数重载其实本质就是名字不一样了而已.C语言没有.所以按照C语言导出.
如果熟悉PE的应该知道导出函数的时候都有一个导出表.而这个导出表则存储着DLL导出的函数.
PS: 调用约定不同.导出函数的函数名就不同. 如果我们以C调用约定风格导出的话.那么函数名就不会重命名.
例如:
导出函数代码.
extern "C" __declspec(dllexport) int _cdecl RetMyAddNumber(int a, int b)
{
return a + b;
} extern "C" __declspec(dllexport) int _cdecl RetMySubNumber(int a, int b)
{
return a - b;
}
直接在函数定义的时候顺便导出了.也可以在函数声明上导出.如果给别人使用.并且是隐式调用的话.需要给.h声明文件.
2.第二种方式 .def文件导出
def文件导出很方便.
首先要创建一个.def文件在自己的工程中.
按照语法导出.
语法:
EXPORTS
函数名 @编号
函数名 @编号 NONAME
函数名就是导出的时候函数名.编号的话就是导出的时候可以有编号.
编号的作用: 有得时候如果动态调用DLL. (loadlibrary + GetProcAddress)那么我们可以直接GetProcAddress(DLL句柄, (LPCSTR)编号) 这样来调用我们的DLL
使用Def文件导出上图我们编写的两个函数.
LIBRARY 说的是要指明我们导出的DLL的名字. 我们的名字就是DLL 所以就给了.
EXPORTS就是导出函数.
我们要导出的函数只有一个 RetMyAddNumber @ 1. 这个函数的编号就是1. 所以我们Get的使用使用编号调用也好. 名字调用也好.
PS: 注意一下.如果我们使用.def文件导出. 那么就不能使用Extern "C" 这个名字了.也不要使用关键字了.
3.使用DLL
使用DLL有两种方式.第一种就是显式调用.另一种则是隐式调用
1.显示调用
显示调用很简单.
1.定义函数指针.
2.使用LoadLibrary加载DLL,返回DLL句柄
3.使用GetProcAddress(dll句柄,你要获取的函数名或者编号)
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#pragma comment(lib,"staticlib.lib")
typedef int (*_cdecl PFN)(int, int); //定义函数指针.要使用DLL int main()
{
//使用导出的全局变量 HMODULE hdll = LoadLibrary(TEXT("Dll.dll"));
PFN pAdd = (PFN)GetProcAddress(hdll, "RetMyAddNumber");
int nValue = pAdd(, ); printf("nValue = %d \r\n ", nValue);
getchar();
return ;
}
2.隐式调用
隐示调用就很简单了.在生成DLL的时候.会对应生成lib. 我们直接使用这个lib即可. 跟上图使用静态lib库一样. 但是需要注意我们也需要DLL
这个lib库只是辅助信息.并不跟上面你的静态库lib一样.上面的静态库lib里面是有实质性的代码的.
例如以下伪代码:
#inclue "xxx头" #pragma comment(lib,"dll的lib") __declspec(dllimport) int MyAdd(int a,int b); 引入声明即可.如果我们的头文件引入了
则不用写.
PS: 静态lib库的代码使用的时候会跟exe链接在一起. 在汇编程序中看 就是 Call 地址. 而 dll库则是 Call [地址] 间接调用.
真正用到的时候才会把地址填写.
Win32编程之静态库编写与使用.动态链接库的编写与使用的更多相关文章
- C 高级编程3 静态库与动态库
http://blog.csdn.net/Lux_Veritas/article/details/11934083http://www.cnblogs.com/catch/p/3857964.html ...
- Yuchuan_Linux_C 编程之三 静态库的制作和使用
一.整体大纲 二.静态库的制作 1)命名规则 lib + 库的名字 + .a 例如:libyuchuan.a2)制作步骤: 1). 生成对应的.o文件 -- ...
- windows中静态库lib和动态dll的区别及使用方法
1. 静态库lib和动态dll的区别 1.1 项目类型 VS在建Win32项目时,有以下选项: windows应用程序控制台应用程序DLL静态库最后两个类型:DLL和静态库,这两种项目类型是不可以单独 ...
- Windows下静态库与动态库的创建与使用
Windows下静态库与动态库的创建与使用 学习内容:本博客介绍了Windows下使用Visual C++ 6.0制作与使用静态库与动态库的方法. --------CONTENTS-------- 一 ...
- vc6静态库的生成和调用
转自vc6静态库的生成和调用 1.静态库的生成: 在vc6.0++中Ctrl+N选择Projects下的Win32 Static Library,Project name:SumLib,点击OK,下一 ...
- Windows下静态库的制作与使用
参考 静态链接 VS 动态链接 静态库 VS 动态库 实验环境 OS:Windows10 企业版 IDE:Visual Studio 2017旗舰版 前言 静态链接库与动态链接库都是共享代码的方式,如 ...
- C++windows内核编程笔记day11 win32静态库和动态库的使用
windows库程序: 静态库: 源码被链接到调用的程序或动态库,被调用时,代码最少有1份,文件后缀.LIB 动态库: 函数被程序或其它动态库调用,被调用时,代码仅仅有1份,文件后缀.DLL 静态库( ...
- C、C++的Makefile的编写以及动、静态库的制作调用(包括MAC地址的获取及MD5加密)
一.C代码 静态库 四个.h.c文件 add.h #ifndef ADD_H #define ADD_H int add(int a,int b); #endif add.c #include < ...
- 【WIN32编程】利用汇编写cs1.6辅助
这篇文章本来在2018.5.1号就写完发圈子去了,这两天跟朋友在网吧打单击才想起来,就顺便把内容发上去把 作者:admin-神风 用CE找到功能的地址 CS1.6下载地址:https://pan.ba ...
随机推荐
- 解决redis连接错误:MISCONF Redis is configured to save RDB snapshots, but it is currently not able to...
今天Redis服务器在连接redis数据库时突然报错:MISCONF Redis is configured to save RDB snapshots, but it is currently no ...
- Injection
what java EE提供了注入机制,使您的对象能够获取对资源和其他依赖项的引用,而无需直接实例化它们.通过使用将字段标记为注入点的注释之一来装饰字段或方法,可以在类中声明所需的资源和其他依赖项.然 ...
- OC中重写set和get方法、懒加载
在写OC程序的时候,在很多时候我们会用到重写set或者get方法,重写这两个方法大多是用于刷新数据,比如懒加载. 意思就是说当你去调用set或者get方法时,系统会去调用重写的get或者set方法,这 ...
- 图像处理及opencv汇总
OPENCV——C++ 1.windows基于vs2017的opencv安装 2.为opencv添加contrib库 3.opencv源码编写规则 4.OpenCV库框架结构 5.OpenCV从2到3 ...
- Exp2 后门原理与实践-------20164325王晓蕊
Exp2 后门原理与实践 任务一:使用netcat获取主机操作Shell,cron启动 1.windows获取linux shell 1.1 ipconfig 查看本机查看以太网适配器(8)的ipv ...
- 二进制安装mysql5.7
1.创建用户和组 groupadd mysql useradd -r -g mysql mysql 2.上传二进制包至/usr/local下解压并改名为mysql tar zxvf mysql-5.7 ...
- Koa 学习笔记
开始 就像官网上说的,一切框架都从一个"Hello World"开始,首先我们新建一个 package.json,内容尽量简单: { "name": " ...
- javascript中数组总结
数组是所有高级语言都会有的东西,数组是JS中使用最多的类型之一,所以掌握JS中数组的用法相当有帮助: 由于JS是一门弱类型的语言,所以数组里面可以放各种不同的数据类型,比如 var a = [1993 ...
- uintAPi 之Renderer.material
Renderer.material public Material material; Returns the first instantiated Material assigned to the ...
- [翻译] Visual Studio 2019 RC版发布
[翻译] Visual Studio 2019 RC版发布 原文: Visual Studio 2019 Release Candidate (RC) now available 今天,我们将分享 V ...