visual studio創建和鏈接dll-顯示鏈接

環境:visual studio 2019

本篇主要介紹如何操作並顯示鏈接dll。

win平臺dll的鏈接有兩種方式,在上一篇visual studio創建和鏈接dll-隱式鏈接中介紹的是如何隱式鏈接,和顯示鏈接的區別主要有兩點。

  1. 隱式鏈接不需要手動加載dll
  2. 隱式鏈接在程序啓動的時候,系統會自動加載exe和dll
  3. 顯示鏈接只在需要的時候才手動加載,同時也要手動釋放
  4. 顯示鏈接在編譯主程序的時候不需要靜態庫做符號鏈接,但需要手動做符號導出

創建DLL

創建DLL和隱式鏈接的方式一樣,這裏不重複介紹,參考visual studio創建和鏈接dll-隱式鏈接即可。

創建dll顯示加載代碼

手動加載dll需要做兩個操作,首先loadLibrary加載dll到進程空間,然後GetProcAddress獲得符號映射。

這兩個功能單獨放在math_loader.cpp中實現。

math_loader.h

#pragma once

#ifndef MATH_LOADER
#define MATH_LOADER
bool loadDLL();
int power(int a);
#endif // !MATH_LOADER

math_loader.cpp

#include "math_loader.h"
#include <Windows.h>
#include <iostream>

using namespace std;

typedef int (*LIB_power)(int a);

LIB_power lib_power;

bool loadDLL()
{
	HMODULE _math_module;

	_math_module = LoadLibraryA("math_lib.dll");
	if (_math_module == NULL)
	{
		cout << "loader load dll failed" << endl;
		return false;
	}

	lib_power = (LIB_power)GetProcAddress(_math_module, "power");
	if (lib_power == NULL) {
		cout << "get proc address failed" << endl;
		return false;
	}
	return true;
}

int power(int a)
{
	return lib_power(a);
}

loader程序中做了三件事。
加載dll:通過loadLibraryA把dll加載到進程空間
獲取符號表映射:GetProcAddress可以通過dll句柄和函數簽名獲得函數地址,它是個指針
聲明和定義dll中的函數:由於應用程序通過指針調用 DLL 函數,因此編譯器不生成外部引用,從而不需要與導入庫鏈接。 但是,必須有一個 typedef 或 using 語句來定義所調用的導出函數的調用簽名。

主程序代碼

顯示鏈接的主程序比隱式鏈接稍微多幾個步驟,我們已經封裝到loader程序中了。

main.cc

#include <iostream>
#include <windows.h>
#include "math_loader.h"

using namespace std;

int main(int argc, char const* argv[])
{
    cout << "loading dll..." << endl;
    if (!loadDLL()) {
        cout << "load dll failed!!" << endl;
        return -1;
    }
    cout << "load dll successfully" << endl;

    int a = 2;

    cout << "power by <math>: " << power(a) << endl;
    return 0;
}

創建solution

顯示鏈接的solution是一個單獨的項目,跟DLL是分開的,不依賴dll項目。參考visual studio創建和鏈接dll-隱式鏈接的主程序創建部分操作即可。

需要修改幾個地方,

  1. main.cc的代碼用顯示鏈接的替換
  2. 不需要def文件
  3. 不需要dll的頭文件

完成後的項目如下,
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-sTJM8y7V-1592190474714)(http://note.youdao.com/yws/res/3908/517C9B9250764E6D99CBEBC61A7A689E)]

編譯生成exe

生成exe的流程跟隱式鏈接一樣,生成後需要把dll也放到exe目錄下,

如果目錄下沒有dll,或者名稱不對,則會拋出異常,

.\app.exe
loading dll…
loader load dll failed
load dll failed!!

正確的如下,
在這裏插入圖片描述

執行exe,結果

.\app.exe
loading dll…
load dll successfully
using custom power
power by : 4

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