__declspec(dllexport)與.def文件
在VC++中,如果生成DLL可以不使用.def文件。只需要在VC++的函數(shù)定義前要加__declspec(dllexport)修飾就可以了。但是使用__declspec(dllexport)和使用.def文件是有區(qū)別的。如果DLL是提供給VC++用戶使用的,只需要把編譯DLL時(shí)產(chǎn)生的.lib提供給用戶,它可以很輕松地調(diào)用你的DLL。但是如果DLL是供VB、PB、Delphi用戶使用的,那么會(huì)產(chǎn)生一個(gè)小麻煩。因?yàn)閂C++對(duì)于__declspec(dllexport)聲明的函數(shù)會(huì)進(jìn)行名稱轉(zhuǎn)換,如下面的函數(shù):
__declspec(dllexport) int __stdcall IsWinNT()
會(huì)轉(zhuǎn)換為IsWinNT@0,這樣你在VB中必須這樣聲明:
Declare Function IsWinNT Lib "my.dll" Alias "IsWinNT@0" () As Long
@的后面的數(shù)由于參數(shù)類(lèi)型不同而可能不同。這顯然不太方便。所以如果要想避免這種轉(zhuǎn)換,就要使用.def文件方式。
EXPORTS后面的數(shù)可以不給,系統(tǒng)會(huì)自動(dòng)分配一個(gè)數(shù)。對(duì)于VB、PB、Delphi用戶,通常使用按名稱進(jìn)行調(diào)用的方式,這個(gè)數(shù)關(guān)系不大,但是對(duì)于使用.lib鏈接的VC程序來(lái)說(shuō),不是按名稱進(jìn)行調(diào)用,而是按照這個(gè)數(shù)進(jìn)行調(diào)用的,所以最好給出。如:
EXPORTS
test @1
vc的dll,delphi調(diào)用的方法:
////K9RtExpr.h
extern "C" __DECDLL
unsigned int _stdcall K9RtSysInterrupt(int nInterruptTag);
extern "C" __DECDLL
unsigned int _stdcall K9RtSysExprm(unsigned int nModuleTag,
float fTimeout,
void * pTestPar,
void * pResultPar
);
// K9RtExpr.cpp
#include "K9RtExpr.h"
#include "RtCtrl.h"
extern "C" __DECDLL
unsigned int _stdcall K9RtSysInterrupt(int nInterruptTag)
{
return CRelayTestControl::Instance()->InterruptTest(nInterruptTag);
}
extern "C" __DECDLL
unsigned int _stdcall K9RtSysExprm(unsigned int nModuleTag,
float fTimeout,
void * pTestPar,
void * pResultPar
)
{
return CRelayTestControl::Instance()->RelayTest(
nModuleTag, fTimeout, pTestPar, pResultPar);
}
///K9RtExpr.def
LIBRARY "K9RtExpr"
DESCRIPTION K9RtExpr Windows Dynamic Link Library'
EXPORTS
K9RtSysInterrupt
K9RtSysExprm
; Explicit exports can go here
//delphi 調(diào)用文件
unit InterfaceFunc;
interface
uses
UnitData,Types;
function K9RtSysExprm(nModuleTag:integer ;
uTimeout:integer;
pTestPar:Pointer;
pResultPar:Pointer) : Integer; stdcall;
function K9RtSysInterrupt(nInterruptType:Integer) : Integer; stdcall;
implementation
const DLLPATH = 'RtBsExpr.dll';
function K9RtSysExprm; external DLLPATH name 'ExperimentRelayTest';
function K9RtSysInterrupt; external DLLPATH name 'InterruptRelayTest';
end.