C++編譯動態庫第三方庫及使用


昨日不可追, 今日尤可爲.勤奮,熾誠,不忘初心

手機淘寶二維碼 掃描      

或者打開連接:程序設計開發 ,掌聲鼓勵,歡迎光臨.


                               C++編譯動態庫第三方庫及使用

爲什麼很多人,尤其各大廠商只給我們庫文件讓我們調用,而不直接提供源代碼呢?這樣的好處是1.把代碼封裝成各個模塊以便複用。 2.省去各種底層調用,省去了大量的代碼複製,更符合面向對象編程理念。3.解決了各種同名衝突的問題。4.最重要的,數據無價,隱匿了具體的實現,保護了知識產權。

一.先定個小目標:做個動態庫。

1.打開VS2017 文件>新建>項目,如下最後確定:

2.項目>添加類,輸入類名Math,確定,如下圖

3.Math.h代碼如下:

#pragma once


namespace wode
{
	double Add(double a, double b);

	double Sub(double a, double b);
}

Math.cpp代碼如下:

#include "pch.h"
#include "MyMath.h"


double wode::Add(double a, double b)
{
	return a + b;
}

double wode::Sub(double a, double b)
{
	return a - b;
}

4.我們要把這兩個函數做成動態庫,那麼,我們要添加一個模塊(.def)文件:

右擊項目名(MathDLL)>添加>新建項,如下所示

輸入:

LIBRARY MathDLL  
EXPORTS              
Add   //導出Add函數
Sub  //導出Sub函數,同理往下寫

*注:不用def模塊文件的話,可以zz哎要導出的函數或者類前面加__declspec(dllexport) 一樣能導出

5.設置項目生成類型:右擊項目名(MathDLL)>常規>配置類型,如圖所示

6.生成動態庫:確認輸出庫對應的平臺,debug X86,即調試版Win32平臺,

右擊項目名(MathDLL)>生成。那麼在項目目錄下,就會生成如下圖所示的文件。

 

這樣,我們就把我們具體實現的代碼(智慧結晶的)封裝到了MathDLL.dll。除非彙編,反編譯技術很牛的大拿,不然,沒人知道你裏面代碼是怎麼實現。心情不美麗時刪庫跑路,拿你一點辦法都沒有。

7.查看動態庫。

庫是做出來了,可鬼知道里面有沒有內容呢,導出正不正確呢,下面就用VS自帶的dumpbin.exe來查看庫的信息。

在第一上面右擊> 打開文件所在位置

Win+R鍵打開cmd窗口,輸入:cd  複製的路徑,如圖:

按回車,現在就定位到dumpbin.exe所在的文件夾目錄了。

如果想要查看MathDLL.dll庫中包含哪些函數,可以使用:dumpbin /exports dll的路徑語法。

參考博客:VS2010dumpbin工具的使用:https://blog.csdn.net/fengbingchun/article/details/43956673

那麼我這裏輸入的是dumpbin /exports C:\VSProjs\MathDLL\Debug\MathDLL.dll

全部過程下圖所示:

庫裏面有我們導出的個函數了,成功!

二.寫個小程序,測試動態庫:

迫不及待,飢渴難耐,趕緊寫個程序測試下動態庫可不可用。

1.右擊解決方案,>添加>新建項目

名稱:TestDLL,確定。這樣解決方案下面就有兩個工程了,右擊TestDLL項目,設爲啓動項目,

2.使用動態庫a:

如果人家提供了.h頭文件,.lib庫文件 .dll動態運行庫文件,那麼,我們需要在項目,屬性中設置包含目錄,庫目錄。具體操作如下:

右擊TestDLL項目屬性,因爲我們要在裏面用到我們上面生成的動態庫

在包含目錄中添加第三方庫.h頭文件的路徑;庫目錄中添加第三方庫.lib文件路徑。並且,要將第三方庫.dll文件拷貝到exe所在的目錄下。

在TestDLL項目的cpp文件中這樣寫:

//添加動態庫頭文件
#include "MyMath.h"
//添加.lib庫文件
#pragma comment(lib,"MathDLL.lib")

int main()
{
	//動態庫中的Add函數,在命名空間wode中
	std::cout << wode::Add(4.2, 3.1) << std::endl;
	//動態庫中的Sub函數,在命名空間wode中
	std::cout << wode::Sub(4.2, 3.1) << std::endl;

	system("pause");
}

運行結果

3.使用動態庫b

有些糟老頭子壞的很,不給你頭文件,.lib庫文件,只給你一個.dll動態庫,然後讓我們去調用dll裏面的xx函數,我們該怎麼辦呢?道友請留步,且聽老夫慢慢說來…

在TestDLL項目的cpp文件中這樣寫:

#include "pch.h"
#include <iostream>
//添加這個頭文件
#include"atlstr.h"


int main()
{
	//定義函數指針
	typedef double(*FUNC)(double, double);
	//動態加載dll文件 
	HMODULE hDLL = LoadLibrary("MathDLL.dll"); 
	if (hDLL != NULL)
	{
		//直接使用原工程函數名
		FUNC Add = FUNC(GetProcAddress(hDLL, TEXT("Add"))); 
		//動態庫中的Add函數,在命名空間wode中
		std::cout << Add(4.2, 3.1) << std::endl;

		//同上Add 
		FUNC Sub = FUNC(GetProcAddress(hDLL, TEXT("Sub"))); 
		//動態庫中的Sub函數,在命名空間wode中
		std::cout << Sub(4.2, 3.1) << std::endl;
	}

	system("pause");
}

報錯如下,右擊TestDLL項目>屬性,在配置屬性>常規>字符集>改成 使用多字節字符集

喲嚯嚯嚯,居然繞過了我的命名空間。6

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章