The Problem
Have you encountered this situation:
you have xxx.dll and xxx.h file, but you do not have xxx.lib,
while you don't want to use LoadLibrary("xxx.dll")
;
you want to implicitly link xxx.lib, then you can call
the functions in the xxx.dll smoothly. Also this article
illustrates some concepts about .DEF file e.g. @ordinal[NONAME]
,
entryname[=internalname], [DATA], [PRIVATE]
. This article is
devoted to these topics. I wish it can help you. Now let's go.
DEF Files
Before we go, I will show something about .DEF.
The syntax for an export definition is:
entryname[=internalname] [@ordinal[NONAME]] [DATA] [PRIVATE]
You can refer to my source code which illustrates how to use that in .DEF files.
What is [PRIVATE]?
;xxx.def
EXPORTS
privatefun PRIVATE
It means that:
privatefun
is only put into xxx.dll, but the symbol (stub)
is not corresponding xxx.lib.
So, when you implicitly link your exe with xxx.lib, if you call privatefun();
you will get LNK2001 : unresolved external symbol "symbol"
What is entryname[=internalname] ?
;xxx.def
EXPORTS
LIBcdeclfun = cdeclfun
It means that:
LIBcdeclfun
is an alias of cdeclfun, note that Visual Basic can't accept '_' (underscore),
also, left name is more meaningful.
What is [DATA] ?
;xxx.def
EXPORTS
vcdata DATA
It means that:
vcdata
is data, not function. You can use __declspec(dllimport)
to import it.
What is [@ordinal[NONAME]] ?
;xxx.def
EXPORTS
fun3 @333 NONAME
It means that:
fun3
only exports with ordinal, not function name. But you can in another yyy.def exports it with the same ordinal,
moreover, you can indicate a function name for this ordinal:
;xxx.def
EXPORTS
Minicfun3 @333
Note : You can use "\VC98\Bin\dumpbin.exe /exports xxx.lib"
(or dll, obj, etc.) to see the export section in PE file.
How to do it?
There are 3 projects in INIT workspace, "Demo", "MINIC", "VCDLL_VB" respectively.
"Demo.exe" depends on "MINIC.lib" and "VCDLL_VB.dll".
extern "C" void cdeclfun()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString str;
str.LoadString(IDS_STRING1);
AfxMessageBox(str);
}
extern "C" void __stdcall fun()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
TCHAR chDLLName[MAX_PATH];
memset(chDLLName,0,sizeof(chDLLName));
GetModuleFileName(AfxGetInstanceHandle(),
chDLLName,MAX_PATH);
AfxMessageBox(chDLLName);
}
extern "C" int __stdcall fun2()
{
return 3;
}
extern "C" long __stdcall fun3(long a)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString str;
str.LoadString(IDS_STRING2);
return (long)AfxMessageBox(str);
}
extern "C" void __stdcall privatefun()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
AfxMessageBox(_T("call into VCDLL_VB!privatefun"));
}
int vcdata=12345;
; VCDLL_VB.def : Declares the module parameters for the DLL.
LIBRARY "VCDLL_VB"
DESCRIPTION 'VCDLL_VB Windows Dynamic Link Library'
EXPORTS
fun
fun2
fun3 @333 NONAME
LIBcdeclfun=cdeclfun
vcdata DATA
privatefun PRIVATE
extern "C" void LIBcdeclfun()
{
}
extern "C" void __stdcall fun()
{
}
extern "C" int __stdcall fun2()
{
return 3;
}
extern "C" long __stdcall Minicfun3(long a)
{
return a;
}
extern "C" void __stdcall Minic(int b)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
AfxMessageBox(_T("CString in MINIC"));
}
int vcdata=6789;
; MINIC.def : Declares the module parameters for the DLL.
LIBRARY "VCDLL_VB"
DESCRIPTION 'MINIC Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
fun
fun2
Minicfun3 @333
vcdata DATA
LIBcdeclfun
Minic
Other important stuff
If the dll export its functions by ordinal, still you can call it. Simply you set a new name for the ordinal
; VCDLL_VB.def
EXPORTS
fun3 @333 NONAME
and a corresponding one as in
; MINIC.def
EXPORTS
Minicfun3 @333
In addition, you can export your function.
The compiler and linker don't complain, but the Operating System's loader will
complain.
; MINIC.def
EXPORTS
Minic ;This function isn't existing in original .dll
when you run Demo.exe, you will get an error dialog below, if you
uncomment the lines as suggested in the source code.
Conclusion
As you known, MFCxxx.dll exports its functions by ordinal,
which can save much space. There is an article in MSDN about
Q131313 HOWTO: Create 32-bit Import Libraries Without .OBJs or Source. You can
email me at
bub_zhang@wistron.com.cn