日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

动态链接库(DLL)开发基础

發(fā)布時(shí)間:2023/12/9 编程问答 78 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态链接库(DLL)开发基础 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本周我的博客涉及到動態(tài)鏈接庫的基礎(chǔ)開發(fā)。我在剛開始學(xué)習(xí)動態(tài)鏈接庫的開發(fā)、在網(wǎng)上找DLL開發(fā)基礎(chǔ)知識教程時(shí)發(fā)現(xiàn)網(wǎng)上的資料還是太雜,對初學(xué)者不太友好,于是我就著手寫了這篇博客,本篇博客知識有DLL簡介、DLL的兩種制作方式、隱式調(diào)用顯式調(diào)用兩種調(diào)用方式以及最后的代碼實(shí)例,編譯器是VS2019。純小白教學(xué),希望能對剛?cè)腴T的你有所幫助。最后,如果感覺文章還可以的話請一鍵三連哦。

DLL簡介

動態(tài)鏈接庫英文為DLL,是Dynamic Link Library的縮寫。DLL是一個(gè)包含可由多個(gè)程序,同時(shí)使用的代碼和數(shù)據(jù)的庫。動態(tài)鏈接就是把調(diào)用的函數(shù)所在文件模塊(DLL)和調(diào)用函數(shù)在文件中的位置等信息鏈接進(jìn)目標(biāo)程序,程序運(yùn)行的時(shí)候再從DLL中尋找相應(yīng)函數(shù)代碼,因此在發(fā)布和運(yùn)行時(shí)需要相應(yīng)DLL文件的支持。

優(yōu)點(diǎn):當(dāng)程序使用 DLL 時(shí),具有以下的優(yōu)點(diǎn): 使用較少的資源,當(dāng)多個(gè)程序使用同一個(gè)函數(shù)庫時(shí),DLL
可以減少在磁盤和物理內(nèi)存中加載的代碼的重復(fù)量。這不僅可以大大影響在前臺運(yùn)行的程序,而且可以大大影響其他在 Windows
操作系統(tǒng)上運(yùn)行的程序。 推廣模塊式體系結(jié)構(gòu)DLL
有助于促進(jìn)模塊式程序的開發(fā)。這可以幫助您開發(fā)要求提供多個(gè)語言版本的大型程序或要求具有模塊式體系結(jié)構(gòu)的程序。模塊式程序的一個(gè)示例是具有多個(gè)可以在運(yùn)行時(shí)動態(tài)加載的模塊的計(jì)帳程序。
簡化部署和安裝當(dāng) DLL 中的函數(shù)需要更新或修復(fù)時(shí),部署和安裝 DLL 不要求重新建立程序與該 DLL 的鏈接。此外,如果多個(gè)程序使用同一個(gè)
DLL,那么多個(gè)程序都將從該更新或修復(fù)中獲益。

DLL的兩種制作方法

使用_declspec方式創(chuàng)建動態(tài)庫

1.打開vs2019,新建一個(gè)動態(tài)鏈接庫,輸入項(xiàng)目名稱,點(diǎn)擊創(chuàng)建。


2. 在頭文件創(chuàng)建dll.h頭文件,在源文件創(chuàng)建dll.cpp文件

3. 在dll.h和dll.cpp中各加入下列代碼
dll.h

#ifdef BUILD_DLL #define API_SYMBOL _declspec(dllexport) #else #define API_SYMBOL _declspec(dllimport) #endif // BUILD_DLLextern "C" API_SYMBOL int convert_array(int* data, int len);

dll.cpp
注意最開始加入頭文件#include “pch.h”,否則會報(bào)錯(cuò)

#include "pch.h" #include "dll.h" #include <iostream> using namespace std;int convert_array(int* data, int len) {for (int i = 0; i < len; i++){cout << data[i] << ",";}cout << endl;int nTotal = 0;for (int i = 0; i < len; i++){nTotal += data[i];--data[i];}return nTotal; }

如圖所示:


4. 右擊項(xiàng)目DLL01,點(diǎn)擊重新生成,當(dāng)出現(xiàn)下面截圖代表DLL生成成功。

5.打開相應(yīng)目錄,可發(fā)現(xiàn)生成的文件。

使用模塊定義文件.def創(chuàng)建動態(tài)庫

該方法相比于第一種方法簡便很多。
1、2步同上
3. 創(chuàng)建dll.h文件,內(nèi)容如下:

#pragma once int convert_array(int* data, int len);

創(chuàng)建dll.cpp文件,文件內(nèi)容同上dll.cpp.
截圖如下:


4.創(chuàng)建.def文件
右擊源文件-》添加-》新建項(xiàng)-》代碼-》模板定義文件,點(diǎn)擊添加

在模板定義文件中加入以下代碼:

LIBRARY Dll02 EXPORTS convert_array @1

其中Dll02、convert_array分別是項(xiàng)目名和函數(shù)名,可更改。有幾個(gè)函數(shù)后面@幾,按順序加。如:

LIBRARY Dll EXPORTS convert_array @1 add @2 sub @3
  • 右擊項(xiàng)目DLL02,點(diǎn)擊重新生成,當(dāng)出現(xiàn)下面截圖代表DLL生成成功。
  • 打開項(xiàng)目對應(yīng)目錄可發(fā)現(xiàn)已經(jīng)生成相應(yīng)的文件。
  • DLL的兩種調(diào)用方式

    隱式調(diào)用

    1.首先創(chuàng)建一個(gè)控制臺應(yīng)用。右擊解決方案-》添加-》新建項(xiàng)目-》控制臺應(yīng)用,創(chuàng)建一個(gè)名為Isinvokedll的控制臺應(yīng)用。如下圖所示:



    2.在生成的Isinvokedll.cpp文件里聲明頭文件 #include “dll.h”,這時(shí)include會標(biāo)紅,因?yàn)檫@兩個(gè)項(xiàng)目沒在一個(gè)文件夾內(nèi),編譯器不知道dll.h文件的位置,這時(shí)需要我們手動配置文件依賴。
    右擊Isinvokedll文件 -》屬性 -》C/C++ -》附加包含目錄。

    點(diǎn)擊三個(gè)點(diǎn),就會出現(xiàn)文件的路徑,選擇文件夾,確認(rèn),應(yīng)用,確認(rèn)。

    3.然后include就不標(biāo)紅了。
    此時(shí)再往頭文件里加入

    #pragma comment (lib,"Dll01.lib")

    這是告訴編譯器與該dll相對應(yīng)的.lib文件所在的路徑和文件名。在生成dll文件時(shí),鏈接器會自動為其生成一個(gè)對應(yīng)的.lib文件,該文件包含了dll導(dǎo)出函數(shù)的符號名和序號(并沒有實(shí)際的代碼)。在應(yīng)用程序中,.lib文件將作為dll的替代文件參與編譯,編譯完成后,.lib文件就不需要了。
    添加完后還需要配置該lib文件的附加庫目錄。與配置的dll.h文件類似。
    右擊項(xiàng)目—》屬性—》鏈接器—》常規(guī)—》附加庫目錄,添加Dll01.lib的文件路徑。

    一般相對路徑在項(xiàng)目文件的debug目錄下,如下圖所示:

    4. 添加下列代碼到Isinvokedll文件夾中

    #include <iostream> #include "dll.h" #pragma comment (lib,"Dll01.lib")int main() {int arr[] = { 3,6,7,8 };int nLen = sizeof(arr) / sizeof(int);int nTotal = convert_array(arr, nLen);std::cout << "數(shù)組元素求和結(jié)果:" << nTotal << std::endl;std::cout << "數(shù)組元素新值:" << std::endl;for (int i = 0; i < nLen; i++){std::cout << arr[i] << ",";} }
  • 右擊項(xiàng)目,設(shè)為啟動項(xiàng),運(yùn)行項(xiàng)目,如圖所示,項(xiàng)目運(yùn)行成功。

  • 顯式調(diào)用

    顯示調(diào)用不需要配置各種文件路徑和附加庫,大概分為5步,

  • 聲明頭文件 #include <Windows.h>
  • 創(chuàng)建一個(gè)別名,它引用的函數(shù)類型需要和dll中的導(dǎo)出函數(shù)一致。
  • 加載DemoDll.dll動態(tài)庫文件。
  • 獲取dll中函數(shù)的地址。
  • 調(diào)用函數(shù)。
  • 釋放動態(tài)庫句柄。
  • 實(shí)例如下所示:

    #include <iostream> #include <Windows.h>//第一步,創(chuàng)建一個(gè)別名,它引用的函數(shù)類型需要和dll中的導(dǎo)出函數(shù)一致。 typedef int (*LPDO_ARRAY)(int* pArr, int nlen); int main() {HINSTANCE hDll;//定義一個(gè)實(shí)例句柄,引用動態(tài)庫;LPDO_ARRAY lpDo_array;//定義一個(gè)函數(shù)指針,用來指向?qū)С龊瘮?shù)//第二步,加載DemoDll.dll動態(tài)庫文件hDll = LoadLibrary(L"Dll02.dll");if (hDll != NULL){//第三步,獲取dll中函數(shù)的地址lpDo_array = (LPDO_ARRAY)GetProcAddress(hDll, "convert_array");if (lpDo_array != NULL){//第四步,調(diào)用函數(shù)int nArr[] = { 1,2,4,6 };int nlen = sizeof(nArr) / sizeof(int);int nRet;//通過函數(shù)指針lpDo_array調(diào)用函數(shù)nRet = lpDo_array(nArr, nlen);std::cout << "返回值:" << nRet << std::endl;std::cout << "數(shù)組新值: ";for (int i = 0; i < nlen; ++i){std::cout << nArr[i] << ",";}}//第五步,釋放動態(tài)庫句柄FreeLibrary(hDll);}}

    運(yùn)行截圖:

    over!

    總結(jié)

    以上是生活随笔為你收集整理的动态链接库(DLL)开发基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。