I'm writing clone DLL's, and needing them to be drop in replacements for programs which already are linked. I do not wish programs linked against my replacement DLL/.Lib to be forced to import by ordinal; however, I do want programs which are already linked against the original DLL to be able to import by ordinal and not be broken by my replacement. -- therefore, I need to export my functions by name but preserve a mapping of ordinals.
How can I do this?
If I create a .def file like this (Interface.def):
LIBRARY Interface
EXPORTS
??0Interface@@QAE@ABV0@@Z @1
??0Interface@@QAE@XZ @2
??1Interface@@MAE@XZ @3
??4Interface@@QAEAAV0@ABV0@@Z @4
??_7Interface@@6B@ @5
?bIsBluetoothAddress@Interface@@SA_NABV?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@@Z @6
?bIsUSBAddress@Interface@@SA_NABV?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@@Z @7
?bIsWiFiAddress@Interface@@SA_NABV?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@@Z @8
?getBluetoothAddressFromResource@Interface@@SAXABV?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@AAV23@@Z @9
?getFantomLoadStatus@Interface@@SA?AW4TFantomLoadStatus@@XZ @10
?getFriendlyNameFromResourceString@Interface@@SA_NABV?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@AAV23@@Z @11
?pzSambaAddress@Interface@@2PBDB @12
allocateNxtInterface @13
bIsExecutableFileType @14
bIsPairedBluetoothName @15
destroyInterface @16
and, in the header file for Interface.h, I made sure to put:
#ifndef __INTERFACE_H__
#ifndef __INTERFACE_EXPORT__
#define __INTERFACE_EXPORT__ __declspec( dllimport )
#endif
class __INTERFACE_EXPORT__ Interface { /* definitions omitted in this example. */
}
extern "C" {
Interface* allocateInterface( void );
void destroyInterface( Interface * );
bool bIsExecutableFileType( Interface * );
bool bIsPairedBluetoothName( Interface * );
}
But, even so --
When I use it under Visual Studios 2008 (version 9) any program linked to the .Lib it creates will try to import by ordinals strictly -- which is NOT what I want. I thought NONAME was required in the .def to get the bad behavior -- but somehow it's happening even without the switch....( see .def file above )
This is how I do the build of the dll, and the test program as a batch file from the command line....
cl /nologo /Zi /EHsc /c Interface.cpp
rem TO make the .def file from the original .dll, with closest mangled names in obj file.
rem uncomment this line: python dll2def.py Interface.obj InterfaceA.dll
link /nologo /debug /DLL /def:Interface.def Interface.obj /NODEFAULTLIB:LIBCMT msvcrt.lib user32.lib atls.lib
cl /nologo /Zi /EHsc /c test.cpp
link /nologo /debug /map /mapinfo:exports test.obj Interface.lib
Yet, after I run the buld.bat script, shown above, test.exe shows ordinals:
Which is NOT what I wanted.
dumpbin.exe /imports
Dump of file test.exe
File Type: EXECUTABLE IMAGE
Section contains the following imports:
Interface.dll
4303E0 Import Address Table
4301F4 Import Name Table
0 time date stamp
0 Index of first forwarder reference
Ordinal 13
Ordinal 12
KERNEL32.dll
430228 Import Address Table
43003C Import Name Table
0 time date stamp
0 Index of first forwarder reference
266 GetTickCount
3D0 SetEnvironmentVariableA
55 CompareStringW
D9 EnterCriticalSection
...
So: How do I explicitly get cl.exe or link to use the NAME even when ordinals are available?