Visual Studio 2015 C++支持的dll生成及呼叫 2021.3.1
- 1、開發環境
- 2、DLL介紹
- 3、C++創建并呼叫自定義dll元件(同一個解決方案下)
- 3.1 新建C++專案來生成DLL
- 3.2 新建客戶端C++專案呼叫dll(同一解決方案下)
- 4、C++專案本地呼叫dll(不同解決方案)
- 4.1 將 DLL 標頭(.h檔案所在目錄)添加到專案的包含目錄
- 4.2 將 DLL 匯入庫(.lib檔案所在目錄)添加到專案的庫目錄
- 4.3 應用所呼叫dll(.dll檔案)的本地部署
- 4.3.1 手動復制dll
- 4.3.2 在生成后事件中復制dll
- 5、C#專案本地呼叫dll
- 5.1 為C#專案進行dll的本地應用部署(兩種dll檔案復制方式)
- 5.1.1 方式一:手動復制dll相關檔案
- 5.1.2 方式二:專案后期生成事件命令列復制
1、開發環境
宇宙第一最強IDEVisual Studio 2015


2、DLL介紹
在 Windows 中,元件 (DLL) 是作為函式和資源的共享庫的一種可執行檔案, 動態鏈接是作業系統功能, 它可使執行檔案呼叫函式或使用存盤在單獨檔案中的資源, 可從使用這些函式和資源的可執行檔案中對其分別進行編譯和部署,
DLL 不是獨立的可執行檔案, DLL 在呼叫它們的應用程式的背景關系中運行, 作業系統將 DLL 加載到應用程式的記憶體空間中, 此操作要么在加載應用程式時(隱式鏈接)完成,要么在運行時按需(顯式鏈接)完成 , DLL 還可以在可執行檔案之間輕松共享函式和資源, 多個應用程式可同時訪問記憶體中單個 DLL 副本的內容,
靜態鏈接將靜態庫中的所有物件代碼復制到生成時使用它的可執行檔案中, 動態鏈接僅包括 Windows 在運行時用于查找和加載含有資料項或函式的 DLL 所需的資訊, 創建 DLL 時,還將創建包含此資訊的匯入庫, 生成呼叫 DLL 的可執行檔案時,聯結器會使用匯入庫中的匯出符號來為 Windows 加載程式存盤此資訊, 當加載程式加載 DLL 時,該 DLL 會映射到你的應用程式的記憶體空間中, 如果存在,則呼叫 DLL 中的特殊函式 DllMain,以執行 DLL 所需的任何初始化,
盡管 DLL 和應用程式都是可執行檔案模塊,但它們之間也存在很多不同之處, 對用戶來說,最明顯的區別在于不能直接運行 DLL, 從系統的角度來看,應用程式和 Dll 之間有兩個基本差異:
一是應用程式可以在系統中同時運行其自身的多個實體, 而 DLL 只能有一個實體,
二是應用程式可以作為行程進行加載, 它可以管理諸如堆疊、執行執行緒、全域記憶體、檔案句柄和訊息佇列之類的資源, 而 DLL 不能管理這些資源,
使用 DLL 的潛在缺點是,應用程式不是自包含的, 它依賴于一個獨立的 DLL 模塊的存在:在安裝程序中必須親自部署或驗證的模塊,
3、C++創建并呼叫自定義dll元件(同一個解決方案下)
3.1 新建C++專案來生成DLL
打開VS2015,選單欄中找到檔案并點擊,彈出新建專案視窗,選擇Visual C++下的Win32專案后再下方輸入專案名稱,瀏覽專案保存位置后點擊確定,


下面選擇目標平臺為Release和x64,然后在解決方案資源管理器下找到頭檔案,右鍵選擇添加新建項,會彈出添加新項視窗,在添加新項視窗中選擇頭檔案后輸入名稱為Mydll.h并點擊添加即可,



在打開的Mydll.h檔案中寫入以下代碼:
#pragma once
// 匯出函式,使用“ _stdcall ” 標準呼叫
extern "C" _declspec(dllexport) int Add(int a, int b);
extern "C" _declspec(dllexport) int Minus(int a, int b);
extern "C" _declspec(dllexport) int Multiply(int a, int b);
extern "C" _declspec(dllexport) int Divide(int a, int b);
extern "C" _declspec(dllexport) void SayHello();
接下來需要在解決方案資源管理器下找到源檔案,右鍵選擇添加新建項


在打開的Mydll.cpp檔案中撰寫自定義函式的實作代碼如下:
#include <iostream>
using namespace std;
#include "Mydll.h"
int Add(int a, int b)
{
return a + b;
}
int Minus(int a, int b)
{
return a - b;
}
int Multiply(int a, int b)
{
return a * b;
}
int Divide(int a, int b)
{
if(b!=0) return a / b;
else
{
std::cout << "除數為0!" << std::endl;
return -1;
}
}
void SayHello()
{
std::cout << "Hello world!" << std::endl;
}


Win+E打開系統的檔案資源管理器查看生成的dll檔案,發現在D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\Mydll\x64\Release檔案夾下生成了6個檔案,包括Mydll.dll、Mydll.exp、Mydll.iobj、Mydll.ipdb、Mydll.lib和Mydll.pdb,

而新建的Mydll.h頭檔案和Mydll.cpp源檔案則保存到了Mydll專案的Mydll檔案夾下,如下圖所示,

到此為止,自定義的dll相關檔案就已經編譯生成(Mydll.cpp為源檔案就不提了),包括頭檔案Mydll.h、庫檔案Mydll.lib和DLL檔案Mydll.dll以及Mydll.exp、Mydll.iobj、Mydll.ipdb和Mydll.pdb,
3.2 新建客戶端C++專案呼叫dll(同一解決方案下)
首先需要明確上述已經生成了dll檔案,但我們想要呼叫這個dll則只需要關注三個檔案:Mydll.h、Mydll.lib和Mydll.dll,
這里新建一個呼叫dll的C++控制臺專案,與Mydll專案放到了同一個解決方案下,所以直接點擊檔案下的添加,選擇新建專案,

在添加新專案視窗中,點擊Visual C++后選擇右側的Win32 控制臺應用程式,輸入專案名稱為TestMydll后點擊確定即可,

點擊下一步,選擇空專案后確定


在解決方案資源管理器下的TestMydll的源檔案上右鍵點擊添加,選擇新建項,

在添加新項視窗中,選擇C++檔案(.cpp)后輸入名稱為TestMydll.cpp后點擊添加,

首先在TestMydll.cpp中寫入不涉及dll呼叫的C++基本代碼:
#include <iostream>
using namespace std;
int main()
{
int a = 1, b = 1;
std::cout << "初始值為a="<<a <<",b="<< b << std::endl;
system("pause");
return 0;
}
先在TestMydll專案上右鍵選擇生成,生成后會產生D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\Mydll*x64\Release**目錄,

在解決方案資源管理器中將TestMydll專案設為啟動專案后就可以后啟動本地除錯,除錯結果如下所示


除錯成功


下面為TestMydll客戶端專案設定所呼叫dll的包含目錄和庫目錄,在解決方案資源管理器下的TestMydll專案上右鍵選擇屬性,打開TestMydll專案的屬性頁,在配置屬性的VC++目錄下,將包含目錄設定為Mydll.h所在檔案夾,將庫目錄設定為Mydll.lib所在檔案夾

同時在TestMydll屬性頁視窗下的聯結器的輸入中,附加依賴項設定為Mydll.lib

然后修改TestMydll.cpp代碼來呼叫Mydll.dll里面的函式,并將Mydll.dll元件檔案復制到D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\Mydll\x64\Release目錄下即可(因為這里Mydll專案和TestMydll專案在同一個解決方案下,所以Mydll.dll就和TestMydll.exe自動在同一個檔案夾下了),最后在TestMydll專案上右鍵選擇重新生成后啟動本地Windows除錯器即可成功運行,
完整的呼叫dll代碼如下:
#include <iostream>
using namespace std;
#include "Mydll.h"
int main()
{
int a = 100, b = 20;
std::cout << "初始值為a=" << a << ",b=" << b << std::endl;
std::cout << Add(a, b) <<std::endl;
std::cout << Minus(a, b) << std::endl;
std::cout << Multiply(a, b) << std::endl;
std::cout << Divide(a, b) << std::endl;
SayHello();
system("pause");
return 0;
}


最后專案生成檔案夾下的內容如下:

4、C++專案本地呼叫dll(不同解決方案)
部署應用時,還必須部署它使用的 DLL, 若要使你生成的或從第三方加入的 DLL 可用于應用,最簡單的方法就是將其放在應用所在的同一目錄中, 這稱為“應用本地部署” ,在本地部署中,庫檔案以及可執行檔案安裝在應用程式檔案夾中,
用VS 2015新建C++控制臺專案,選擇空專案后確定



新建源檔案C++TestMydll.cpp,并撰寫以下代碼,同時選擇Release和x64.
#include <iostream>
using namespace std;
#include "Mydll.h"
int main()
{
int a = 100, b = 20;
std::cout << "初始值為a=" << a << ",b=" << b << std::endl;
std::cout << Add(a, b) <<std::endl;
std::cout << Minus(a, b) << std::endl;
std::cout << Multiply(a, b) << std::endl;
std::cout << Divide(a, b) << std::endl;
SayHello();
system("pause");
return 0;
}

可以看到上圖源代碼中頭檔案和函式名稱都標紅,提示找不到,下面進行配置,
4.1 將 DLL 標頭(.h檔案所在目錄)添加到專案的包含目錄
VS的解決方案中找到專案并右鍵選擇屬性,打開專案的屬性頁視窗,找到VC++目錄的包含目錄,將所呼叫dll對應的.h檔案所在目錄(D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\Mydll\Mydll)復制到這里,


4.2 將 DLL 匯入庫(.lib檔案所在目錄)添加到專案的庫目錄
VS的解決方案中找到專案并右鍵選擇屬性,打開專案的屬性頁視窗,找到VC++目錄的庫目錄,將所呼叫dll對應的.lib檔案所在目錄(D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\Mydll\x64\Release)復制到這里,


同時VS的解決方案中找到專案并右鍵選擇屬性,打開專案的屬性頁視窗,找到聯結器的輸入,右側找到附加依賴項輸入dll對應的.lib檔案的檔案名Mydll.lib,

這時代碼就不會標紅了,如下圖所示,但如果直接運行會報錯,并提示無法找到Mydll.dll檔案,


4.3 應用所呼叫dll(.dll檔案)的本地部署
一般來說,應用所呼叫dll檔案的本地部署分為手動復制dll和在生成后事件中復制dll兩種方式,
4.3.1 手動復制dll
將D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\Mydll\x64\Release\Mydll.dll檔案復制到D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\C++TestMydll\x64\Release檔案夾下,然后在VS中重新生成并啟動本地除錯器運行即可成功,



4.3.2 在生成后事件中復制dll
通過解決方案資源管理器的C++TestMydll專案上右鍵,在配置屬性的常規下可以看到輸出目錄為D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\C++TestMydll\x64\Release

像
S
o
l
u
t
i
o
n
、
Solution、
Solution、Platform、
C
o
n
f
i
g
u
r
a
t
i
o
n
和
Configuration和
Configuration和OutDir等宏變數都表示特定的檔案目錄,

首先洗掉D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\C++TestMydll\x64\Release檔案夾下的Mydll.dll檔案,然后在專案上右鍵打開屬性頁視窗,找到生成事件->后期生成事件,命令列中輸入以下命令將Mydll.dll檔案在專案運行后期自動復制到專案x64\Release檔案夾下:

xcopy /y /d "..\..\Mydll\$(IntDir)Mydll.dll" "$(OutDir)"


此時啟動本地除錯器即可成功運行,同時可以看到Mydll.dll檔案會被自動復制到C++TestMydll專案的x64\Release檔案夾下


5、C#專案本地呼叫dll
不像C++專案呼叫自定義dll那樣復雜,C#呼叫自定義dll只需將所有dll相關的生成檔案放到自己的生成檔案夾下同時在代碼中添加dll自定義函式匯入宣告即可,
首先,新建一個C#控制臺應用程式


現在需要在主函式main內部添加兩行代碼后,解決方案配置選擇Release,解決方案平臺選擇x64后,點擊啟動本地除錯器開始運行:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSharpConsoleApplication
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("This is a CSharp Console Application!");
Console.ReadLine();
}
}
}


接下來在代碼中添加dll參考介面,并在代碼的主函式外添加dll自定義函式匯入宣告,在主函式內部添加函式呼叫代碼,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;//添加dll參考介面
namespace CSharpConsoleApplication
{
class Program
{
//添加dll自定義函式匯入宣告
[DllImport("Mydll.dll", EntryPoint = "Add")]
static extern int Add(int a, int b);
[DllImport("Mydll.dll", EntryPoint = "Minus")]
static extern int Minus(int a, int b);
[DllImport("Mydll.dll", EntryPoint = "Multiply")]
static extern int Multiply(int a, int b);
[DllImport("Mydll.dll", EntryPoint = "Divide")]
static extern int Divide(int a, int b);
[DllImport("Mydll.dll", EntryPoint = "SayHello")]
static extern void SayHello();
static void Main(string[] args)
{
int a = 50, b = 5;
Console.WriteLine("This is a CSharp Console Application!");
Console.WriteLine(Add(a, b));
Console.WriteLine(Minus(a, b));
Console.WriteLine(Multiply(a, b));
Console.WriteLine(Divide(a, b));
SayHello();//添加函式呼叫代碼
Console.ReadLine();
}
}
}


這時如果直接啟動本地除錯器開始運行,結果不會成功,因為Mydll.dll相關檔案還沒有對CSharpApplication專案進行本地部署,會如上圖所示報錯,提示無法加載Mydll.dll檔案,
5.1 為C#專案進行dll的本地應用部署(兩種dll檔案復制方式)
為C#專案部署本地應用的dll相關檔案只涉及到Mydll.dll、Mydll.exp、Mydll.iobj、Mydll.ipdb、Mydll.lib和Mydll.pdb六個檔案,
5.1.1 方式一:手動復制dll相關檔案
將D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\Mydll\x64\Release檔案夾下的上述六個檔案手動復制到D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\CSharpConsoleApplication\CSharpConsoleApplication\bin\x64\Release檔案夾下即可,然后在VS2015中啟動本地除錯器即可成功運行,



5.1.2 方式二:專案后期生成事件命令列復制
首先保證D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\CSharpConsoleApplication\CSharpConsoleApplication\bin\x64\Release檔案夾下沒有Mydll.dll相關的檔案即可


將C++專案自定義生成檔案夾下dll相關檔案復制到C#專案生成檔案夾下的命令列代碼,需要在CSharpApplication專案上右鍵->屬性打開相關設定視窗,找到生成事件,在生成事件的后期生成事件命令列中輸入如下代碼后啟動本地除錯器即可成功運行,
xcopy /y /d "D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\Mydll\x64\Release\*.*" "D:\Program Files (x86)\Microsoft Visual Studio 2015\myprojects\CSharpConsoleApplication\CSharpConsoleApplication\bin\x64\Release\"



轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/265506.html
標籤:其他
上一篇:IT學習資源——倪靈版
