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.pswp.cn/news/277798.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/277798.shtml
英文地址,請注明出處:http://en.pswp.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)位置開始,它根據一組函數指令…

(待完成)qbxt2019.05 總結2 - 數位DP

數位 DP 嚴格來說其實并不是 DP……它只是個單純的計數問題 但是怎么說呢……現在大家似乎都把數位 DP 叫這個名字,所以……我們還是……叫它 DP 額什么是數位 DP 呢? 一句話概括——一類求在 K 進制下m滿足條件的數的數量有多少個的算法 常見的問題形式…

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"#">大…

第十周總結

失望光年轉載于:https://www.cnblogs.com/daisy99lijing/p/11064924.html

LC #45 JS

效率低下 最起碼容易看得懂&#xff1f;將就看吧 /*** param {number[]} nums* return {number}*/ var jump function(nums) {let len nums.length;if(len < 1){return 0;}function calPossibleLastStep(index){let res [];if(index > len){return res;}if(index <…

python之爬蟲(四)之 Requests庫的基本使用

什么是Requests Requests是用python語言基于urllib編寫的&#xff0c;采用的是Apache2 Licensed開源協議的HTTP庫如果你看過上篇文章關于urllib庫的使用&#xff0c;你會發現&#xff0c;其實urllib還是非常不方便的&#xff0c;而Requests它會比urllib更加方便&#xff0c;可以…

https://blog.csdn.net/cscscscsc/article/details/50

https://blog.csdn.net/cscscscsc/article/details/50899522轉載于:https://blog.51cto.com/7237876/2129682

linux下安裝mysql說明

1.msyql下載 mysql-5.6.33 通用版&#xff0c;linux64位&#xff0c;官方下載地址&#xff1a;http://dev.mysql.com/downloads/mysql/5.6.html#downloads。也可以通過命令下載&#xff1a;wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.33-linux-glibc2.5-x86…

win8下cocos2dx-3.2+VS2012環境配置及項目創建

這是本人CSDN的第一篇博客&#xff0c;因為假期在學校做實訓項目接觸到了cocos2dx&#xff0c;覺得是一個特別適用強大&#xff0c;有不錯的可移植性&#xff08;雖然可移植性不錯&#xff0c;但實際上寫好的游戲往Android上移植&#xff0c;我的隊友廢了好大勁。。。&#xff…

Android通過透明度設置背景變暗

變暗 WindowManager.LayoutParams lpgetWindow().getAttributes(); lp.alpha0.3f; getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); getWindow().setAttributes(lp);變為原來的樣子 WindowManager.LayoutParams lpgetWindow().getAttributes(); lp.alpha1.…

BZOJ4557:[JLOI2016/SHOI2016]偵察守衛——題解

https://www.lydsy.com/JudgeOnline/problem.php?id4557 小R和B神正在玩一款游戲。這款游戲的地圖由N個點和N-1條無向邊組成&#xff0c;每條無向邊連接兩個點&#xff0c;且地圖是連通的。換句話說&#xff0c;游戲的地圖是一棵有N個節點的樹。 游戲中有一種道具叫做偵查守衛…

Mac系統下Homebrew的安裝和使用Homebrew安裝python

這里向大家推薦一個東西&#xff0c;Mac下很好用的東西&#xff0c;叫做Homebrew。剛開始接觸Mac的時候&#xff0c;我也沒聽過這個東西&#xff0c;但裝了以后真的覺得&#xff0c;TMD太碉堡了。引用一句話&#xff1a;Homebrew is the easiest and most flexible way to inst…

JS中的深拷貝

前言&#xff1a;我們經常會遇到想要將一個對象為己所用&#xff0c;但又不能污染原對象的需求&#xff0c;這就涉及到了js對象的深拷貝。 比如說在VUE的子組件中&#xff0c;父組件傳過來的數據中若是有對象&#xff0c;而子組件需要用父組件的數據進行初始化并且有另做他用的…

Mac下cocos2dx-3.2+Xcode環境配置和項目創建

這是有關環境配置的第二篇教程&#xff0c;第一篇講的是win8下的環境配置。這里我們使用C。所有如果你用其他語言如Lua和js進行cocos2d開發&#xff0c;那么可以再找一找其他的配置文檔。下面要說Mac os 下 cocos2dx-3.2Xcode的環境配置&#xff0c;這里我使用的是Xcode 5.1.1。…

對flex-grow和flex-shrink的深入理解

flex彈性布局&#xff0c;如果子元素寬度之和大于或者小于父元素寬度&#xff0c;空間就會存在剩余和不夠&#xff0c;flex默認不換行&#xff0c;除非設置flex-wrap,那么這種情況下&#xff0c;有兩個重要的屬性&#xff0c;flex-grow和flex-shrink. flex-grow默認值為0&#…

拿下京東榜單第五首戰告捷,看聯想手機如何上演王者歸來

618對于手機行業來說是一個非常重要的日子&#xff0c;京東618上銷量的高低在某種程度上就代表了該手機品牌在國內市場的影響力&#xff0c;以及在行業中所處的位置。因此&#xff0c;今年的618各大手機品牌卯足了勁在京東平臺上展開較量。榮耀、小米、VIVO、OPPO等手機品牌相繼…

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

作為一個程序員&#xff0c;經常要配置變量&#xff0c;可能要更改hosts文件&#xff0c;或者你閑著沒事兒尋找homebrew給你安裝的東西在什么地方。Mac OS的內核是Unix&#xff0c;Linux/Unix系統出于系統安全和用戶安全的考慮&#xff0c;會把一些與系統相關的文件隱藏&#x…