VS2017生成一个简单的DLL文件 和 LIB文件——C语言

下面我们将用两种不同的姿势来用VS2017生成dll文件(动态库文件)和lib文件(静态库文件),这里以C语言为例,用最简单的例子,来让读者了解如何生成dll文件(动态库文件)

 

生成动态库文件

姿势一:

第一步:新建一个项目

 

第二步:选择Windows桌面向导(这里先不要去管上面的“动态链接库(DLL)”)

 

 第三步:选择动态链接库,并空项目打勾√

 

 第四步:添加一个.c源文件

 

第五步:(因为这里以C语言为例子,将后缀改为.c)

 

第六步:在c文件中输入一个简单的函数这里使用了_declspec(dllexport),但_declspec(dllexport)并不是必须的,后面一种方法将不使用_declspec(dllexport)

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

 

第七步:新建一个头文件

 

 第八步:在头文件中输入函数的声明

 

第九步:编译

 

第十步:Debug文件夹下的两个文件DLL.dll和DLL.lib就是我们要使用的两个文件了

因为使用的_declspec(dllexport),虽然这里我们只编译了一次,却生成了dll和lib两个文件

 

 

姿势二

 

第一步到第五步和上面的步骤一模一样,这里从第六步开始讲起

 

第六步:在c文件中输入一个简单的函数(注意这里就没有使用_declspec(dllexport)

 

第七步:添加一个头文件

 

第八步:在头文件中输入函数的声明

 

第九步:编译

 

第十步:这时在Debug文件里就可以看出两种方法的区别了,第二种方法没有加 _declspec(dllexport) 只有一个dll文件,如果我们也想要lib文件,需要额外几个步骤

 

生成lib文件

 

第十一步:点击项目——》DLL属性

 

第十二步:配置属性——》项目默认值——》配置类型,把动态库(.dll) 改为 静态库(.lib)

 

第十三步:编译

 

第十四步:这个时候Debug文件夹里面就多出了一个lib文件

从上面两个例子可以看出:

在生成dll文件(动态库文件)时,如果不使用_declspec(dllexport)那么就只有dll文件,在这种情况下就无法使用#pragma comment来隐式装载动态库(因为需要lib文件),只能使用LoadLibrary来显式装载动态库(使用Loadlibrary只需要dll文件

如果使用了_declspec(dllexport)那么就既有dll文件,也有lib文件

 

还有一点需要注意的是,如果在源文件(.c文件)中函数的定义没有_declspec(dllexport),但是在头文件中函数的声明使用了_declspec(dllexport)此时编译产生的文件只有dll文件如果改成源文件中有_declspec(dllexport),头文件中没有_declspec(dllexport),那么编译产生的文件既有dll文件也有lib文件

(导出dll文件时最好还是在源文件和头文件中都加上_declspec(dllexport)

笔者记录了一下加与不加_declspec(dllexport)对导出dll文件大小的影响,以上面的代码为例

(造成dll文件大小不同的原因,笔者暂时无法给出解释,待补充)

 

 

生成静态库文件

 

和生成dll文件步骤相似,这里就不再赘述了,直接上图

第一步:

 

第二步:建议把预编译标头的勾去掉,(不去掉也没事,只是本文为了简洁,让读者更清楚的生成步骤)

 

第三步:

 

第四步:

 

第五步:

在源文件中输入以下代码:

int sum(int a, int b)
{return a + b;
}

 

第六步:

 

第七步:

 

第八步:

 

第九步:编译,可以看到Debug文件夹下有一个lib文件

 

(注意:不要像我一样傻fufu的,在导出lib文件的时候还加上_declspec(dllexport)(之前我的确这么干过),如果加了_declspec(dllexport),在Debug文件夹里面也只有lib文件,lib文件也能正常使用,

但是不建议加)

还有一点就是,生成dll文件(动态库文件)时产生的lib文件,和生成lib文件(静态库文件)时产生的lib文件的作用不相同,从文件大小也能看出来(一个1.58KB一个3.92B)

关于lib和dll文件的区别可以看一下这一盘文章:lib 和 dll 的区别、生成以及使用详解

 

 笔者记录了一下加与不加_declspec(dllexport)对导出lib文件大小的影响,以上面的代码为例

(至于为什么加了_declspec(dllexport)后,lib文件会出现0.02KB的差别,笔者暂时无法给出解释,待补充)

 

有的读者可能会发现在网上很多博客写关于生成dll文件时,头文件里面的写法是这样的

 

刚接触预处理命令的读者看着可能会有点不好理解,下面对上面的头文件中的代码逐个分析,笔者将上面的代码分为两个个部分(对预处理命令不是很熟悉的读者可以先看一下这一篇随笔:

预处理命令使用详解----#if、#endif、#undef、#ifdef、#else、#elif

第一部分:

#pragma once
#ifdef DLL_EXPORTS
#define DLL _declspec(dllexport)#else
#define DLL _declspec(dllimport)#endif

把上面的代码翻译一下就是:如果DLL_EXPORTS这个宏名已经被定义,那么DLL就等价于_declpsec(dllexport),否者DLL就等价于_declspec(dllimport),#pragma once保证了该头文件只被包括(#include)一次,

在很多头文件中都可以看到#pragma once,比如stdio.h

读者这个时候可能就有疑问了,明明我没有#define DLL_EXPORTS,为什么是执行#define DLL _declspec(dllexport)而不是#define DLL _declspec(dllimport)呢?

首先读者需要知道的是DLL_EXPORTS是一个预定义的宏,因为我们是生成的是DLL文件

可以在属性->配置属性->C/C++->预处理器中看到

现在读者应该清楚了,在生成DLL文件时,编译器已经预定义了DLL_EXPORTS这个宏名,如果我们是生成的应用程序

上面的代码写成

#ifdef
```
#else
```
#endif

这种形式是为了方便在使用的时候lib或者dl文件时,需要引入头文件的时候方便一点,不需要对头文件做任何的修改(因为如果我们使用的配置类型是“应用程序(.exe)”,那么就没有预定义DLL_EXPORTS)

 

第二部分:

#ifdef _cplusplus
extern "C"
{
#endifDLL int sum(int a, int b);
#ifdef _cplusplus
}
#endif

把上面的代码翻译一下就是:如果是C++文件(.cpp后缀)那么就是

extern "C"
{DLL int sum(int a, int b);
}

如果不是C++文件,那么就是

DLL int sum(int a, int b);

关于extern "C"作用,可以看一下这篇文章:深入理解C/C++混合编程(关于#ifdef __cplusplus extern "C" {...}的用法)

 

总结一下:

生成动态库文件

 

头文件:

 1 #pragma once
 2 #ifdef DLL_EXPORTS
 3 #define DLL _declspec(dllexport)
 4 
 5 #else
 6 #define DLL _declspec(dllimport)
 7 
 8 #endif
 9 
10 #ifdef _cplusplus
11 extern "C"
12 {
13 #endif
14     DLL int sum(int a, int b);
15 #ifdef _cplusplus
16 }
17 #endif

 

源文件:

1 _declspec(dllexport) int sum(int a, int b)
2 {
3     return a + b;
4 }

 

编译之后产生:

 

生成静态库文件:

 

头文件:

 1 #pragma once
 2 
 3 #ifdef _cplusplus
 4 extern "C"
 5 {
 6 #endif
 7     int sum(int a, int b);
 8 #ifdef _cplusplus
 9 }
10 #endif

 

源文件:

1 int sum(int a, int b)
2 {
3     return a + b;
4 }

 

编译后产生:

 

到这里本文就基本结束了,上面详细叙述了生成dll文件(动态库文件)和lib文件(静态库文件)的步骤,关于lib文件和dll文件的使用将在另一篇随笔中详细介绍

转载于:https://www.cnblogs.com/lanhaicode/p/10798385.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/277798.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hive数据类型及文本文件数据编码

本文参考Apache官网,更多内容请参考:https://cwiki.apache.org/confluence/display/Hive/LanguageManualTypes 1. 数值型 类型支持范围TINYINT1-byte signed integer, from -128 to 127SMALLINT2-byte signed integer, from -32,768 to 32,767INT/INTEGE…

Python绘图Turtle库详解

转载:https://blog.csdn.net/zengxiantao1994/article/details/76588580 Turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x、纵轴为y的坐标系原点,(0,0)位置开始,它根据一组函数指令…

mac使用brew update无反应解决办法

为什么80%的码农都做不了架构师?>>> mac系统中使用brew作为包管理工具,类似centos中的yum,ubuntu中的apt-get,在使用brew update的使用,有时候会长时间无反应,或者中途断开连接,这是…

2018-2019-2 20175223 实验三《敏捷开发与XP实践》实验报告

目录 北京电子科技学院(BESTI)实验报告实验名称:实验三 敏捷开发与XP实践实验内容、步骤与体会:一、实验三 敏捷开发与XP实践-1二、实验三 敏捷开发与XP实践-2三、实验三 敏捷开发与XP实践-3四、实验三 敏捷开发与XP实践-4五、代码…

(八)路径(面包屑导航)分页标签和徽章组件

一&#xff0e;路径组件 路径组件也叫做面包屑导航。 <ol class"breadcrumb"><li><a href"#">首页</a></li><li><a href"#">产品列表</a></li><li><a href"#">大…

python之爬虫(四)之 Requests库的基本使用

什么是Requests Requests是用python语言基于urllib编写的&#xff0c;采用的是Apache2 Licensed开源协议的HTTP库如果你看过上篇文章关于urllib库的使用&#xff0c;你会发现&#xff0c;其实urllib还是非常不方便的&#xff0c;而Requests它会比urllib更加方便&#xff0c;可以…

win8下cocos2dx-3.2+VS2012环境配置及项目创建

这是本人CSDN的第一篇博客&#xff0c;因为假期在学校做实训项目接触到了cocos2dx&#xff0c;觉得是一个特别适用强大&#xff0c;有不错的可移植性&#xff08;虽然可移植性不错&#xff0c;但实际上写好的游戏往Android上移植&#xff0c;我的队友废了好大劲。。。&#xff…

Mac系统下Homebrew的安装和使用Homebrew安装python

这里向大家推荐一个东西&#xff0c;Mac下很好用的东西&#xff0c;叫做Homebrew。刚开始接触Mac的时候&#xff0c;我也没听过这个东西&#xff0c;但装了以后真的觉得&#xff0c;TMD太碉堡了。引用一句话&#xff1a;Homebrew is the easiest and most flexible way to inst…

Mac下cocos2dx-3.2+Xcode环境配置和项目创建

这是有关环境配置的第二篇教程&#xff0c;第一篇讲的是win8下的环境配置。这里我们使用C。所有如果你用其他语言如Lua和js进行cocos2d开发&#xff0c;那么可以再找一找其他的配置文档。下面要说Mac os 下 cocos2dx-3.2Xcode的环境配置&#xff0c;这里我使用的是Xcode 5.1.1。…

Mac OS使用技巧之一:查看Finder中的.bash_profile等系统隐藏文件

作为一个程序员&#xff0c;经常要配置变量&#xff0c;可能要更改hosts文件&#xff0c;或者你闲着没事儿寻找homebrew给你安装的东西在什么地方。Mac OS的内核是Unix&#xff0c;Linux/Unix系统出于系统安全和用户安全的考虑&#xff0c;会把一些与系统相关的文件隐藏&#x…

win8下cocos2dx3.2移植android平台及代码打包APK

cocos2dx程序不能只在VS2012下运行&#xff0c;迟早是要搬运到Android和IOS上的。Windows下移植IOS平台先搁下不说比较困难&#xff0c;而且只有越狱的苹果机才可以运行&#xff0c;而且毕竟IOS高端、小众。这里主要讲一下移植Android&#xff0c;windows下cocos2dx打包成APK和…

【转】用Fiddler做抓包分析详解

1.为什么是Fiddler? 抓包工具有很多&#xff0c;小到最常用的web调试工具firebug&#xff0c;达到通用的强大的抓包工具wireshark.为什么使用fiddler?原因如下&#xff1a; a.Firebug虽然可以抓包&#xff0c;但是对于分析http请求的详细信息&#xff0c;不够强大。模拟http…

Mac下cocos2dx3.2移植android平台详细教程

本文是cocos2dx移植android的第二篇教程&#xff0c;笔者深深感觉&#xff0c;cocos2dx移植android平台是永远的痛啊。。。下面讲一下笔者花费一个周研究的Mac OS下的cocos2dx3.2android配置首先要准备的东西&#xff08;1&#xff09;下载cocos2dx3.2 http://www.cocos2d-x.o…

robotframework(12)修改用户密码(从数据库查询短信验证码)

一、testcase&#xff1a;修改用户密码需要6个参数&#xff08;短信验证码、设置的新密码、用户已登录的userid及用户唯一标识、接口校验码、被修改的手机号&#xff09;&#xff0c;故先准备这些参数 二、用户登录请求&#xff0c;&#xff08;获取userid、用户唯一标识&#…

Mac OS使用技巧之二:修改变量Path解决android: command not found

前一阵子&#xff0c;一直在搞Mac OS和win8下cocos2dx移植android平台的方法。一步步从无到有的慢慢摸索出来。最近发现了一个小问题&#xff0c;有关环境变量配置的写下来分享给大家。就是我们在windows8下查看已有android SDK的版本&#xff0c;需要在CMD里面输入&#xff1a…

Jenkins架构

一. Master 和slave.下图阐述了master-slave交互的架构&#xff1a;在上面这个分布式的构建环境中&#xff0c;Jenkins master主要负责如下&#xff1a;接收构建触发&#xff08;比如&#xff0c;一个提交到GitHub后&#xff09;发送通知&#xff08;比如&#xff0c;在构建失败…

Mac OS使用技巧之三:发射无线网络信号的方法

许多人知道在windows下可以直接借助各种辅助软件来直接发射wifi信号&#xff0c;比如360wifi&#xff0c;猎豹wifi。或者可以直接在命令行里面设置。许多人却不知道Mac系统也有方便快捷发射无线信号的功能。下面讲一下利用Mac OS发射无线网络信号的方法。前提&#xff1a;你的电…

纪实:对CSDN博客系统的一些质疑

我是一个对编程充满热情的在校大学生&#xff0c;本来我是怀着满腔热情来到CSDN写博客&#xff0c;记录和分享自己的学习经历。却被这糟糕的博客系统一次次的泼冷水。写这篇博客确实是因为心中十分不甘和特别生气&#xff0c;所以我决定要把自己的遭遇写出来&#xff0c;我自己…

php框架之laravel

常见问题: 1. 访问网站500错误 这是因为laravel的缓存路径没有找到 laravel缓存文件路径是在 config/cache.php中设置&#xff0c;默认存在storage文件夹中 解决:需要保证storage/framework下面创建 sessions&#xff0c; views, cache 文件夹并确保可写权限 转载于:https://ww…

MySQL的命令合集

2019独角兽企业重金招聘Python工程师标准>>> MySQL客户端操作 $db$是数据库名称$table$是数据表名称$field$是数据表里的字段名称有些语句最后加上**/G**可以使结果更美观数据库相关 创建数据库,修改数据库 create database $db$; 使用默认设置create database $db$…