This has been discussed in parts on many places, but it still wont work for me.
I have a dll compiled from delphi source, which exports one function under two names, inspecting the dll using
>> dumpbin /EXPORTS MyLibrary.dll
i get the following output:
...
17 3 00070A88 MyFunction
...
46 24 00070A88 _MyFunction@48
...
so i created a file called MyLibrary.def with the following content:
EXPORTS
MyFunction
_MyFunction@48
And generated an import library using
>> lib /def:MyLibrary.def /OUT:MyLibrary.lib /MACHINE:x86
Inspecting the new lib-file with dumpbin i see the following:
...
_MyFunction
...
__MyFunction@48
...
So somehow the lib application added one underscore in front of the function name. (why?)
Then i try to use this function in a c++ program, compiling with Microsoft Visual Studio C++ 2010 Express (using the lib file):
// MyLibrary.h
# define DllImport(Type) __declspec (dllimport) Type __stdcall
extern "C" DllImport(void)MyFunction(...);
// main.cpp
#import "MyLibrary.h"
...
MyFunction(....);
...
This should now work, as far as i could find out, but i get the following linker error:
... error LNK2001: Unresolved external sympol "__imp__MyFunction@48".
I don't understand why this goes wrong (i dont realy understand how the whole thing works ...) but i tried two more things.
- Renamed my function in MyLibrary.h and main.h from MyFunction to _MyFunction
- Result: it works! But why? I dont want to rely on this, since something is obviously wrong.
- Renamed my function back to MyFunction and removed the underscore in the def-File, generated the lib file again and tried to compile
- Result: compilation succeeds, but when starting the program i get
MyApp - Entry Point Not Found
---------------------------
The procedure entry point MyFunction@48 could not be located
in the dynamic link library MyLibrary.dll.
I think one needs a deeper understanding of the inner working of the lib tool and the linker, but i couldn't find any information about this so far.
KB131313 explains one problem you'll face trying to use the
lib
utility for this:Your functions uses stdcall, not cdecl, as we can tell from the
@
in the function name. Nevertheless, the KB article explains what to do instead:Declare the function as it would be in C++, but for export instead of for import.
You've already done that, mostly. You have the calling convention right, but the
@48
on the end means it needs to have 48 bytes' worth of parameters. The function will expect to have that data pushed on to the stack, and before it returns, the function will pop that much off. Your use of...
in the declaration is incompatible with that.If you don't know what the specific argument list should really be, then go ahead and just define 12
int
parameters, so at least the stack structure will be right. (But if you don't know what the list should really be, you're pretty close to doomed anyway.)Write a dummy implementation in C++.
The implementation can be empty. The only requirement is that the code compiles and links.
Compile your own version of MyLibrary.dll from that dummy code.
Make sure it's compatible with the original DLL. Run
dumpbin
on it and see that it exports at least one version of the function names you saw in the original DLL. (You don't need both; your program is only going to use one of the names, and as thedumpbin
output shows, both names go to the same location in the binary, so it doesn't matter which name your program ends up using.)Throw away the DLL and keep just the LIB file.
If the linker still complains that it cannot find
__imp_MyFunction@48
, then remove thedllimport
part from your declaration. That should remove the__imp_
prefix, making the name look more like the Delphi name.If all else fails, you can use run-time dynamic linking instead of load-time. Declare a pointer type for the function, and then use
LoadLibrary
andGetProcAddress
to get access to it.