1. 程式人生 > >VS2010編寫動態連結庫DLL及單元測試用例

VS2010編寫動態連結庫DLL及單元測試用例

本文將建立一個簡單的動態連結庫,並編寫一個控制應用程式使用該動態連結庫,該動態連結庫為“JAVA呼叫動態連結庫DLL之JNative學習”中使用的DLL,只是專案及檔名稱不同。

建立動態連結庫專案:
1、開啟Microsoft Visual Studio 2010,選擇檔案->新建->專案。


2、在新建專案視窗中選擇其他語言->Visual C++->Win32。


3、選擇Win32 專案,設定名稱:simpleDLL,設定解決方案名:simpleDLL。
4、單擊確定,在出現的Win32 應用程式嚮導的概述對話方塊中點選下一步。


5、在應用程式設定中,選擇應用程式型別下的DLL。


6、勾選附加選項下的空專案。
7、單擊完成建立專案。
向動態連結庫新增類:
1、新增新類標頭檔案。右鍵單擊simpleDLL專案,新增->新建項,選擇標頭檔案(.h),設定名稱為simpleDLL,單擊新增。



2、新增新類原始檔。右鍵單擊simpleDLL專案,新增->新建項,選擇C++ 檔案(.cpp),設定名稱為simpleDLL,單擊新增。



3、為新類新增內容。內容如下:

標頭檔案simpleDLL.h:

  1. //------------------ SimpleDLL.h ----------------
  2. #pragma once;
  3. //該巨集完成在dll專案內部使用__declspec(dllexport)匯出
  4. //在dll專案外部使用時,用__declspec(dllimport)匯入
  5. //巨集DLL_IMPLEMENT在SimpleDLL.cpp中定義
  6. #ifdef DLL_IMPLEMENT
  7. #define DLL_API __declspec(dllexport)
  8. #else
  9. #define DLL_API __declspec(dllimport)
  10. #endif
  11. DLL_API int add(int x, int y); //簡單方法
  12. DLL_API constwchar_t* getPlayUrl(constwchar_t* mgrIp, long mgrPort, long materialId);  
  13. DLL_API constchar* getUrl(constchar* mgrIp, long mgrPort, long materialId);  
原始檔simpleDLL.cpp:
  1. //------------------ SimpleDLL.cpp ----------------
  2. //注意此處的巨集定義需要寫在#include "SimpleDLL.h"之前
  3. //以完成在dll專案內部使用__declspec(dllexport)匯出
  4. //在dll專案外部使用時,用__declspec(dllimport)匯入
  5. #define DLL_IMPLEMENT
  6. #include "SimpleDLL.h"
  7. #include<Windows.h>
  8. #include <intrin.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. int DLL_API add(int x, int y)  
  12. {  
  13.     return x+y;  
  14. }  
  15. DLL_API constwchar_t* getPlayUrl(constwchar_t* mgrIp, long mgrPort, long materialId)  
  16. {  
  17.     staticwchar_t url[260] = { 0 };  
  18.     wcscpy_s(url, L"http://中文");  
  19.     wcscat_s(url, mgrIp);  
  20.     wcscat_s(url, L":");  
  21.     wchar_t szPort[20] = { 0 };  
  22.     _ltow_s(mgrPort, szPort, 10);  
  23.     wcscat_s(url, szPort);  
  24.     return url;  
  25. }  
  26. DLL_API constchar* getUrl(constchar* mgrIp, long mgrPort, long materialId)  
  27. {  
  28.     staticchar url[260] = { 0 };  
  29.     strcpy_s(url, "http://中文");  
  30.     strcat_s(url, mgrIp);  
  31.     strcat_s(url, ":");  
  32.     char szPort[20] = { 0 };  
  33.     _ltoa_s(mgrPort, szPort, 10);  
  34.     strcat_s(url, szPort);  
  35.     return url;  
  36. }  

建立引用動態連結庫的應用程式:
1、在解決方案上單擊滑鼠右鍵->新增->新建專案。


2、在新增新專案中選擇其它語言->Visual C++->Win32。


3、選擇Win32 控制檯應用程式,設定名稱:simpleDLLTest。
4、單擊確定,在出現的Win32 應用程式嚮導的概述對話方塊中點選下一步。


5、在應用程式設定中,選擇應用程式型別下的控制檯應用程式。


6、單擊完成建立專案。
在控制檯應用程式中使用類庫的功能:
1、為SimpleDLLTest.cpp新增內容。如下所示:

  1. // SimpleDLLTest.cpp : 定義控制檯應用程式的入口點。
  2. #include "stdafx.h"
  3. #include "../SimpleDLL/SimpleDLL.h" //新增標頭檔案引用
  4. #pragma comment(lib, "..\\..\\SimpleDLL\\Release\\SimpleDLL.lib") //新增lib檔案引用 
  5. #include <process.h>
  6. #include <locale.h>
  7. int _tmain(int argc, _TCHAR* argv[])  
  8. {  
  9.     setlocale(LC_ALL, "chs"); //配置地域化資訊為簡體中文,否則打印出來的中文是亂碼
  10.     wprintf(L"getPlayUrl: %s\r\n", getPlayUrl(L"127.0.0.1", 10087, 1));  
  11.     printf("getUrl: %s\r\n", getUrl("127.0.0.1", 10087, 1));  
  12.     system("pause");  
  13.     return 0;  
  14. }  
2、引用simpleDLL專案。右鍵單擊SimpleDLLTest專案,選擇專案依賴項。


3、依賴於視窗中勾選SimpleDLL,單擊確定。


4、設定SimpleDLLTest專案為活動專案。右鍵單擊SimpleDLLTest專案,選擇設為啟動專案。


6、生成解決方案。Debug執行結果如下:


注意:現在建立的DLL只能由c++呼叫,C語言等其它語言是調用不了的!

我們來用工具看一下,在解決方案上單擊滑鼠右鍵,在Windows資源管理器中開啟資料夾


我編譯的是Release版本,所以開啟Release資料夾,找到SimpleDLL.dll檔案,用Depends工具開啟它


目前編譯的版本對MSVCR100.DLL還有依賴,這樣複製到其它沒有安裝VS2010的電腦上是用不了的;

在專案上單擊滑鼠右鍵,屬性:


在左側的配置屬性中選擇常規,在右側找到MFC的使用,選擇在靜態庫中使用MFC


再看函式,帶有一些特殊字元,這樣c++之外其它語言是調用不了的;我們需要在標頭檔案的函式宣告中新增extern "C"標誌,程式碼如下:

  1. //------------------ SimpleDLL.h ----------------
  2. #pragma once;
  3. //該巨集完成在dll專案內部使用__declspec(dllexport)匯出
  4. //在dll專案外部使用時,用__declspec(dllimport)匯入
  5. //巨集DLL_IMPLEMENT在SimpleDLL.cpp中定義
  6. #ifdef DLL_IMPLEMENT
  7. #define DLL_API __declspec(dllexport)
  8. #else
  9. #define DLL_API __declspec(dllimport)
  10. #endif
  11. extern"C" DLL_API int add(int x, int y); //簡單方法
  12. extern"C" DLL_API constwchar_t* getPlayUrl(constwchar_t* mgrIp, long mgrPort, long materialId);  
  13. extern"C" DLL_API constchar* getUrl(constchar* mgrIp, long mgrPort, long materialId);  
重新編譯,再Depends工具開啟它,可以發現依賴項已經沒有了,函式名稱也正常了: