I'm part of a team reviving a dormant open source project. One of the first things I did was fix the software to build with Visual C++ on Windows. The plan is to distribute the MSVC version in the upcoming release.
The current DLL is built with the __stdcall
calling convention, for reasons I can't explain. No big deal, except it was also built with MinGW and MinGW and Visual C++ disagree about what __stdcall
means. See here for details, but basically MinGW mangles the name like Function@n
and MSVC mangles it like _Function@n
. It's a good reason not to use __stdcall
in your DLLs...
The switch to __stdcall
was important enough to the previous maintainers that they bumped a major version number (because it broke ABI compatibility) when they switched to it and I'm reluctant to bump it again to switch back to __cdecl
.
Basically, I need to convince MSVC to decorate the symbols in the DLL like MinGW does, either with some sort of alias, or just changing the name. I don't care which, as the other software in the suite can be easily rebuilt to call the DLL however is needed - it's existing software I'm worried about.
I suspect I need a .DEF file for this, but I'm reluctant to make one by hand. There's dozens of exported functions.
So here's the question - is there any automated or mostly-automated way to do this?
I was able to write a simple Python script to do this. I don't know if there's an easier way, but this works for me
You'll want pexports (linked from here), and you can run it on your DLL with pexports mylib.dll > mylib-stock.def
. Then run this Python script with fixdefs.py mylib-stock.def mylib.def
and include that while building the library. Seems to work fine. You'll get a file like:
_Function@n
Function@n=_Function@n
Script:
#!/usr/bin/env python
from sys import argv
def fixline(line):
if line.startswith('_'):
line=line.strip()
return "%s\n%s=%s\n" % (line, line[1:], line)
return line
if __name__=="__main__":
if len(argv)!=3:
print "usage %s <input.def> <output.def>" % argv[0]
exit(1)
with open(argv[1], 'r') as input:
with open(argv[2], 'w') as output:
for line in input:
output.write(fixline(line))