VS2013中為C++程序生成lib和dll文件


dll的優點

  代碼復用是提高軟件開發效率的重要途徑。只要某部分代碼具有通用性,就可將它構造成相對獨立的功能模塊並在之后的項目中重復使用。比較常見的例子是各種應用程序框架,ATL、MFC等,它們都以源代碼的形式發布。由於這種復用是“源碼級別”的,源代碼完全暴露給了程序員,因而稱之為“白盒復用”。

  “白盒復用”的缺點有:暴露了源代碼;多份拷貝,造成存儲浪費; 容易與程序員的“普通”代碼發生命名沖突; 更新功能模塊比較困難,不利於問題的模塊化實現;

以上4點概括起來就是“暴露的源代碼”造成“代碼嚴重耦合”。為了彌補這些不足,就提出了“二進制級別”的代碼復用。使用二進制級別的代碼復用一定程度上隱藏了源代碼,對於緩解代碼耦合現象起到了一定的作用。這樣的復用被稱為“黑盒復用”。 說明:實現“黑盒復用”的途徑不只dll一種,靜態鏈接庫甚至更高級的COM組件都是。

對比而言,使用DLL主要有以下優點:使用較少的資源;當多個程序使用同一函數庫時,DLL可以減少在磁盤和物理內存中加載的代碼的重復量。這不僅可以大大影響在前台運行的程序,而且可以大大影響其它在Windows操作系統上運行的程序;推廣模塊式體系結構;簡化部署與安裝。

http://blog.csdn.net/piaoxuezhong/article/details/61201785中介紹了.DLL文件的顯式調用方法,這篇介紹dll文件的生成方法~

---------------------方式一:只生成dll文件-------------------

首先打開VS2013,新建—項目—Win32控制台應用程序(項目名稱:dllTest)---控制台應用程序—空項目---完成
新建一個源文件source.cpp

 1 extern "C" _declspec(dllexport) void myFun();
 2 
 3 #include "iostream"
 4 using namespace std;
 5 void myFun()
 6 {
 7     cout<<"Hello,Jasen_Fu"<<endl;
 8 }
 9 int main()
10 {
11     myFun();
12     return 0;
13 }
  用控制台exe配置類型自己定義函數,並通過主函數調試, 然后可以通過項目——屬性——配置屬性——常規——項目默認值——配置類型下, 選擇動態庫(.dll)選項 然后點擊生成---生成解決方案,會在工程的Debug目錄下生成一個DLL文件(dllTest.dll)

然后就可以按照之前(http://blog.csdn.net/piaoxuezhong/article/details/61201785)的方法顯式調用生成的dll文件了。

注釋:http://www.cppblog.com/Dutyboy/archive/2010/11/15/133699.html

  使用 _declspec(dllexport) 關鍵字從 DLL 導出數據、函數、類或類成員函數。_declspec(dllexport) 會將導出指令添加到對象文件中,不需要使用 .def 文件。extern "C"的真實目的是實現類C和C++的混合編程。在C++源文件中的語句前面加上extern "C",表明它按照類C的編譯和連接規約來編譯和連接,而不是C++的編譯的連接規約。這樣在類C的代碼中就可以調用C++的函數或變量。

  使用extern "C" __declspec(dllexport)聲明導出函數,在DLL中的函數名字保持與導出函數名一致。使用__declspec(dllexport)聲明導出函數,在DLL中的函數名字與導出函數名字不一致,有變化。這些差異主要是使用C方式函數C++方式編譯導致的。在使用GetProcAddress( HMODULE hModule, LPCWSTR lpProcName)函數查找導出函數時,最好在DLL中用extern "C" __declspec(dllexport)聲明導出函數。

---------------------方式二:生成lib文件-------------------

先建立一個控制台工程(新建->工程->控制台程序),添加sub.cpp以及add.h文件。

1 //sub.h
2 #ifndef _SUB_H
3 #define _SUB_H
4 void sub(int a,int b);
5 #endif
1 //sub.cpp
2 #include "sub.h"
3 #include <iostream>
4 
5 void sub(int a,int b)
6 {
7     std::cout<<"差值為:"<<(a-b)<<std::endl;
8 }

  右鍵點擊工程,並選擇工程屬性,選擇靜態鏈接庫(或是一開始新建項目時選擇靜態庫),然后點擊生成--生成解決方案,此時Debug目錄下生成.lib文件。

使用靜態庫

  需要.h文件,lib文件,可以把.h和.lib文件拷貝到新建需要調用項目目錄下: (1)設置項目屬性--vc++目錄--庫目錄為lib所在的路徑 (2)將lib添加到項目屬性--鏈接器--輸入--附加依賴項(或者直接在源代碼中加入#pragma comment(lib, “**.lib”)) (3)在頭文件中添加.h頭文件

 1 #include <iostream>
 2 #include "sub.h"  //鏈接庫的頭文件
 3 using namespaces std;
 4 
 5 #pragma comment(lib,"sub.lib") //加入鏈接庫
 6 
 7 int main()
 8 {
 9     sub(10,5);
10     return 0;
11 }

 

附錄:靜態庫(靜態鏈接庫)、動態庫(動態鏈接庫)的概念

  靜態庫:在鏈接步驟中,連接器將從庫文件取得所需的代碼,復制到生成的可執行文件中,這種庫稱為靜態庫,其特點是可執行文件中包含了庫代碼的一份完整拷貝;缺點就是被多次使用就會有多份冗余拷貝。即靜態庫中的指令都全部被直接包含在最終生成的 EXE 文件中了。在vs中新建生成靜態庫的工程,編譯生成成功后,只產生一個.lib文件 動態庫:動態鏈接庫是一個包含可由多個程序同時使用的代碼和數據的庫,DLL不是可執行文件。動態鏈接提供了一種方法,使進程可以調用不屬於其可執行代碼的函數。函數的可執行代碼位於一個 DLL 中,該 DLL 包含一個或多個已被編譯、鏈接並與使用它們的進程分開存儲的函數。在vs中新建生成動態庫的工程,編譯成功后,產生一個.lib文件和一個.dll文件 靜態庫和動態庫中的lib的區別:http://blog.csdn.net/langb2014/article/details/48392919 靜態庫中的lib:該LIB包含函數代碼本身(即包括函數的索引,也包括實現),在編譯時直接將代碼加入程序當中。 動態庫中的lib:該LIB包含了函數所在的DLL文件和文件中函數位置的信息(索引),函數實現代碼由運行時加載在進程空間中的DLL提供。 總之,lib是編譯時用到的,dll是運行時用到的。如果要完成源代碼的編譯,只需要lib;如果要使動態鏈接的程序運行起來,只需要dll。

參考:

http://blog.csdn.net/langb2014/article/details/48392919

http://www.cnblogs.com/mypsq/p/5060049.html 

http://www.jianshu.com/p/5d2eeeb93590

http://www.itnose.net/detail/6688109.html

http://blog.csdn.net/xiamentingtao/article/details/51055438

http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html

http://www.jellythink.com/archives/111

http://www.cnblogs.com/TenosDoIt/p/3203137.html (lib)

http://www.tuicool.com/articles/jEvYjm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM