前面我們介紹了dll的生成,大多數是使用extern "C"__declspec(dllexport)+函數名的方法導出dll。其實我們還有另一種方法來導出dll。
先介紹參考文獻:
1.dll導出聲明相關
2.VS2012中 C++創建DLL圖解
3.DLL中導出函數的兩種方式(dllexport與.def文件)
4 按序號而不是按名稱從 DLL 導出函數
5.模塊定義 (.Def) 文件
6.VS2010中 C++創建DLL圖解??? :介紹了如何定義def文件
7.MS VS只生成dll,不生成lib
8.VS中def文件對于生成dll和lib文件的作用
然后:
我們可以重點讀一下3和6.即可。8中指出其實def文件的功能相當于extern “C” __declspec(dllexport)
我這里給出一個例子(點擊下載)。證明了此處話的正確性。
貼出代碼為:
testdll.h
#ifndef TestDll_H_
#define TestDll_H_extern "C"
{int Add(int plus1, int plus2);int substract(int a);
}#endif<span style="color:#ff0000;"><strong>
</strong></span>
.cpp
// NewDLL.cpp : 定義 DLL 應用程序的導出函數。
//#include "stdafx.h"
#include "testdll.h"
#include <iostream>
using namespace std;
int Add(int plus1, int plus2)
{int add_result = plus1 + plus2;return add_result;
}int substract(int a)
{return a;
}
調用dll:
#include <Windows.h>
#include <iostream>
#include "testdll.h"typedef int(*Func)(int, int);#pragma comment(lib,"NewDLL.lib")int main()
{HMODULE Hdll = LoadLibrary("NewDLL.dll");if (Hdll != nullptr){Func f = Func(GetProcAddress(Hdll, MAKEINTRESOURCE(2)));if (f != nullptr){std::cout << "input 2 num:";int a, b;std::cin >> a >> b;std::cout << "result is " << Add(a, b);}else{std::cout << "connot find the function " << "add" << std::endl;}FreeLibrary(Hdll);}else{std::cout << "cannot load dll" << "NewDLL.dll" << std::endl;}system("pause");return 0;
}
def定義為:
LIBRARY "NewDLL"
EXPORTS
Add @2 NONAME
substract @1 NONAME
注意:
1. 我們要將dll的頭文件、lib文件都在調用的項目中指明。而且在生成dll的項目中def要指明
選擇工程 > 屬性中的鏈接器,然后找到"輸入"這一項. 在 "模塊定義文件" 中輸入??***.def
2. def文件中指明了函數的順序,并且函數使用?c風格生成,這可以使我們在顯式調用時直接使用函數名或者序號來調用。我們也可以為了節省內存,將函數名去掉,使用NONAME屬性即可。可參考文獻4.上面我們生成的dll就沒有函數名,我們可使用dumpbin查看:
可以看到使用def,就可以基本不用改變頭文件中的函數,我們手動的在def中指明。而且如果你的DLL是提供給VC用戶使用的,你只需要把編譯DLL時產生的.lib提供給用戶,
它可以很輕松地調用你的DLL。但是如果你的DLL是供VB、PB、Delphi用戶使用的,那么會產生一個小麻煩。
因為VC++編譯器對于__declspec(dllexport)聲明的函數會進行名稱轉換,如下面的函數:
__declspec(dllexport) int __stdcall Add()
會轉換為Add@0,這樣你在VB中必須這樣聲明:
Declare Function Add Lib "DLLTestDef.dll" Alias "Add@0" () As Long
@后面的數由于參數類型不同而可能不同。這顯然不太方便。所以如果要想避免這種轉換,就要使用.def文件方式導出函數了。
???????