1. 程式人生 > >VS2013中為C++程式生成lib和dll檔案

VS2013中為C++程式生成lib和dll檔案

dll的優點

程式碼複用是提高軟體開發效率的重要途徑。只要某部分程式碼具有通用性,就可將它構造成相對獨立的功能模組並在之後的專案中重複使用。比較常見的例子是各種應用程式框架,ATL、MFC等,它們都以原始碼的形式釋出。由於這種複用是“原始碼級別”的,原始碼完全暴露給了程式設計師,因而稱之為“白盒複用”。“白盒複用”的缺點有:暴露了原始碼;多份拷貝,造成儲存浪費; 容易與程式設計師的“普通”程式碼發生命名衝突; 更新功能模組比較困難,不利於問題的模組化實現;
以上4點概括起來就是“暴露的原始碼”造成“程式碼嚴重耦合”。為了彌補這些不足,就提出了“二進位制級別”的程式碼複用。使用二進位制級別的程式碼複用一定程度上隱藏了原始碼,對於緩解程式碼耦合現象起到了一定的作用。這樣的複用被稱為“黑盒複用”。
說明:實現“黑盒複用”的途徑不只dll一種,靜態連結庫甚至更高階的COM元件都是。

對比而言,使用DLL主要有以下優點:使用較少的資源;當多個程式使用同一函式庫時,DLL可以減少在磁碟和實體記憶體中載入的程式碼的重複量。這不僅可以大大影響在前臺執行的程式,而且可以大大影響其它在Windows作業系統上執行的程式;推廣模組式體系結構;簡化部署與安裝。

---------------------方式一:只生成dll檔案-------------------

首先開啟VS2013,新建—專案—Win32控制檯應用程式(專案名稱:dllTest)---控制檯應用程式—空專案---完成

新建一個原始檔source.cpp

extern "C" _declspec(dllexport) void myFun();

#include "iostream"
using namespace std;
void myFun()
{
    cout<<"Hello,Jasen_Fu"<<endl;
}
int main()
{
    myFun();
    return 0;
}
用控制檯exe配置型別自己定義函式,並通過主函式除錯,
然後可以通過專案——屬性——配置屬性——常規——專案預設值——配置型別下,
選擇動態庫(.dll)選項
然後點選生成---生成解決方案,會在工程的Debug目錄下生成一個DLL檔案(dllTest.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檔案。

//sub.h
#ifndef _SUB_H
#define _SUB_H
void sub(int a,int b);
#endif
//sub.cpp
#include "sub.h"
#include <iostream>

void sub(int a,int b)
{
    std::cout<<"差值為:"<<(a-b)<<std::endl;
}
右鍵點選工程,並選擇工程屬性,選擇靜態連結庫(或是一開始新建專案時選擇靜態庫),然後點選生成--生成解決方案,此時Debug目錄下生成.lib檔案。

使用靜態庫

需要.h檔案,lib檔案,可以把.h和.lib檔案拷貝到新建需要呼叫專案目錄下:
(1)設定專案屬性--vc++目錄--庫目錄為lib所在的路徑
(2)將lib新增到專案屬性--連結器--輸入--附加依賴項(或者直接在原始碼中加入#pragma comment(lib, “**.lib”))
(3)在標頭檔案中新增.h標頭檔案

#include <iostream>
#include "sub.h"  //連結庫的標頭檔案
using namespaces std;

#pragma comment(lib,"sub.lib") //加入連結庫

int main()
{
    sub(10,5);
    return 0;
}

附錄:靜態庫(靜態連結庫)、動態庫(動態連結庫)的概念

靜態庫:在連結步驟中,聯結器將從庫檔案取得所需的程式碼,複製到生成的可執行檔案中,這種庫稱為靜態庫,其特點是可執行檔案中包含了庫程式碼的一份完整拷貝;缺點就是被多次使用就會有多份冗餘拷貝。即靜態庫中的指令都全部被直接包含在最終生成的 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