摘自https://blog.csdn.net/qq_37059136/article/details/80167388
c++動態(tài)函數(shù)庫的創(chuàng)建與調(diào)用(.def)
痕憶丶2018-05-02 16:11:28
8215收藏? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 9? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
分類專欄:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 靜態(tài)庫和動態(tài)庫? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
動態(tài)庫的創(chuàng)建有兩種方法,之前說過了不使用.def的方法,現(xiàn)在說一下使用.def的方法
環(huán)境VS2005
寫個簡單的動態(tài)庫,里面有兩個函數(shù),能實現(xiàn)加法減法
首先創(chuàng)建一個空項目dll,創(chuàng)建頭文件
,再創(chuàng)建源文件
,再創(chuàng)建模塊定義文件即.def文件
這樣創(chuàng)建一個動態(tài)庫所需的條件就滿足了.
在頭文件
中寫入如下代碼
在源文件
中寫入如下代碼
在源文件的模塊定義文件
中寫入如下代碼
F7生成動態(tài)庫
在.def中第一行是數(shù)據(jù)庫的名字,第二行是固定語句EXPORTS,導(dǎo)出代碼,下面add跟sub后面可以不加@X(這里就有兩種方法導(dǎo)出動態(tài)庫里的函數(shù),后面會說)
隱式調(diào)用
在同一解決方案下創(chuàng)建空WIN32控制臺項目,在源文件中創(chuàng)建
,其代碼如下
運行結(jié)果
這樣隱式調(diào)用就完成了
注意:隱式調(diào)用需要用到動態(tài)庫里的頭文件
和動態(tài)庫文件夾debug里的
,所以.cpp文件夾中一定要包含,可以拷貝兩者到.cpp同一文件夾下,也可以用代碼中的方法.
顯式調(diào)用
在同一解決方案下創(chuàng)建WIN32控制臺空項目,在源文件中創(chuàng)建
,代碼如下
運行結(jié)果
在顯式調(diào)用中,由于使用的是.def的方法,在獲取動態(tài)庫中函數(shù)地址時有兩種方法
AddFunc ADD1 = (AddFunc)GetProcAddress(hdll,(char*)(1));這是在.def文件中add后面加@1的使用方法,當然你也可以使用通用獲取地址方法?AddFunc ADD1 = (AddFunc)GetProcAddress(hdll,"add");
AddFunc ADD1 = (AddFunc)GetProcAddress(hdll,(char*)(1));這句(char*)(1)中1是add后面@的數(shù)字,相當于add在動態(tài)庫中的地址,GetProcAddress的函數(shù)原型里1這個位置數(shù)據(jù)類型是char*類型.
附.def的一些小知識:
.def 文件中的第一條 LIBRARY 語句不是必須的仙逻,但LIBRARY 語句后面的 DLL 的名稱必須正確,即與生成的動態(tài)鏈接庫的名稱必須匹配。此語句將 .def 文件標識為屬于 DLL刃跛。鏈接器將此名稱放到 DLL 的導(dǎo)入庫中挪捕。
EXPORTS 語句列出名稱叛甫,可能的話還會列出 DLL 導(dǎo)出函數(shù)的序號值筹吐。通過在函數(shù)名的后面加上 @ 符和一個數(shù)字痘儡,給函數(shù)分配序號值刊咳。當指定序號值時彪见,序號值的范圍必須是從 1 到 N,其中 N 是 DLL 導(dǎo)出函數(shù)的個數(shù)娱挨。
LIBRARY BTREE
EXPORTS
Insert @1
Delete @2
Member @3
Min @4
“def???文件中的注釋由每個注釋行開始處的分號???(;)???指定余指。注釋不能與語句共享一行,但可以在多行語句的規(guī)范間出現(xiàn)让蕾。
vs2010中使用.def文件導(dǎo)出函數(shù)時需要的設(shè)置?
在vs2010中使用.def文件導(dǎo)出函數(shù)時,要在工程屬性-鏈接器-輸入-模塊定義文件中加入自定義的.def文件名浪规;可用vs的命令提示查看導(dǎo)出函數(shù) dumpbin -exports dllnames
//dll.h
#pragma once
int __stdcall add(int x,int y);
int __stdcall sub(int x,int y);
// no need .def
//extern "C" _declspec(dllexport) int add(int a, int b);
//extern "C" _declspec(dllexport) int sub(int a, int b);
//main.cpp
#include "dll.h"
int _stdcall add(int x,int y)
{
return x+ y;
}
int _stdcall sub(int x,int y)
{
return x - y;
}
//int? add(int x,int y)
//{
//return x+ y;
//}
//
//int? sub(int x,int y)
//{
//return x - y;
//}
所以隱式調(diào)用的意思是,在調(diào)用的useDLL的源代碼中探孝,可以看到用到的只是LIB和.H,
實際上笋婿,運行的時候還是需要用.DLL.
顯式調(diào)用就很明顯說需要dll, 里面沒有對LIB的依賴。
LoadLibrary("ConsoleApplication_GenDLL.dll");
我之前都是顿颅。缸濒。。 沒有隱式顯式的概念粱腻。
編譯的時候lib, #include ... 在設(shè)置中寫 dll. 源代碼中沒有l(wèi)oadlibrary 這樣庇配。這個可能是c和c++的差別。maybe.