如何實現讓自己寫的動態鏈接庫工程 (Dynamic-Link Library Project)和測試工程 (比如Console)在同一個解決方案下調試呢?
下面就拿VS2019的DLL項目搭配控制台設置一下聯合調試:
先創建一個簡單的DLL動態鏈接庫項目,在這里我們把ta命名為"Dll1"。
在Dll1里,添加一個頭文件,在里面添加動態庫中欲導出函數的函數頭,這里我們添加了兩個非常簡單的Add和Sub函數,不過在新版VS的編譯環境下,一定要記得include pch.h這個預編譯文件。
1 //Dll1.h 2 #pragma once 3 #include "pch.h" 4 5 int Add(int a, int b); 6 int Sub(int a, int b);
然后在“源文件”文件夾下添加與頭文件同名的源文件,里面具實現頭文件中聲明的函數。
1 //Dll1.cpp 2 #include "pch.h" 3 #include <iostream> 4 5 using namespace std; 6 7 int Add(int a, int b) { 8 cout << "Starting the function Add: " << endl; 9 return a + b; 10 } 11 12 int Sub(int a, int b) { 13 cout << "Starting the function Sub:" << endl; 14 return a - b; 15 }
下一步為了將我們剛剛寫好的函數以庫文件的形式導出,我們在“源文件”文件夾下添加一個.def的文件使用EXPORTS命令用於導出剛剛寫好的兩個函數。記得在第一行的LIBRARY后面加上以咱們這個dll工程為名編譯生成的dll動態庫文件(這里就是Dll1.dll)注意!:library的名字一定要寫對。這樣一個.lib的靜態庫就在該工程的文件夾下生成了。
1 //Dll1.def 2 LIBRARY "Dll1.dll" 3 4 EXPORTS 5 6 Add 7 Sub
不過這時大家可能會發現單單這樣的Dll的工程在編譯的時候可能會報錯,顯示“xxx.dll is not a valid Win32 application.”這是因為在編譯的時候,生成的xxx.dll文件並不是一個可執行的程序,vs無法將生成的dll調起來。但細心的同學可能會發現,雖然此時編譯報錯了,但點開dll工程的debug文件夾會發現此時的xxx.dll 動態庫文件已經如願的生成了。
於是接下來,咱們再創建一個簡單的控制台程序,在這里我們把ta命名為Dll1_test,將剛剛生成的dll動態庫加載進去,並實現聯合調試:
咱們在同一個解決方案(solution)下,右鍵解決方案的名稱,點擊添加,選擇一個新工程,或一個現有已寫好的測試工程。這里我們選擇一個新的控制台工程,然后設好名字以后點擊創建,這里我們將ta命名為Dll1_test,這樣就在同一個解決方案下又添加了一個工程。
為了能在新的測試工程中使用先前在dll工程中寫好的函數,需要在測試工程中包含dll工程的頭文件(這樣工程在編譯的時候才不會報錯),這里有兩種方法將dll工程中包含函數聲明的頭文件包含進來的方法:
1. 將dll工程中的頭文件直接復制到新的測試工程中;
2. 使用相對路徑的方法找到dll工程的頭文件。
這里我們選擇相對路徑的方法: ..\ 在相對路徑中表示前一級目錄。
本次實例中兩個工程的文件夾是同級的文件夾。 加入了頭文件以后,再使用#pragma comment命令將dll工程生成的動態鏈接庫包含進來(那里面有具體的函數實現,雖然看不到)。由於#pragma命令的使用方法很復雜,這里我們就不再細說了。下面就是在測試工程的main函數下寫具體的函數調用了。這里我們只調用了一個Add函數作為示例。
1 // Dll1_test.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 // 3
4 #include <iostream>
5 #include "..\Dll1\Dll1.h"//包含dll工程的頭文件 來獲取函數聲明
6 #pragma comment(lib, "Dll1")//將生成的動態庫調進來
7 using namespace std; 8
9 int main() 10 { 11 int a, b; 12 cin >> a >> b; 13 int c; 14 c = Add(a, b); 15 cout << "The result of the function is :" << c << endl; 16 return 0; 17 }
心急的同學們如果在此時就點擊的編譯,可能會發現編譯出錯了,而且和之前的錯誤一模一樣,這是因為,這是整個解決方案的啟動工程仍是咱們最開始創建的dll工程,需要將test測試程序設置為此時解決方案的啟動工程。這里我們先右鍵解決方案,在Project Dependency(項目依賴/獨立)中選擇test測試工程depends on咱們的dll工程。確定后再右鍵test測試工程選擇“設置為啟動項目”("Set as StartUp Project")
而就算這樣在編譯的時候還會發現竟然還會報錯!"Cannot open file xxx.lib" 原因是找不到函數具體實現的靜態庫的位置,還需要我們手動的告訴編譯器此次測試的庫到底在哪。於是我們右鍵測試工程,在最下面的屬性里面,找到Linker->general,在additional library directories里面加入我們dll工程生成靜態庫.lib文件的地址,同樣這里使用相對路徑的方法。
設置好以后確定,這時再點擊調試,就可以實現dll工程與控制台工程在同一個解決方案中聯合調試啦!