设置MSVC DLL与__stdcall MinGW DLL ABI兼容

时间:2013-02-26 05:33:16

标签: visual-c++ dll mingw dllexport

我是一个恢复休眠开源项目团队的一员。我做的第一件事就是修复了在Windows上使用Visual C ++构建的软件。计划是在即将发布的版本中分发MSVC版本。

当前的DLL是使用__stdcall调用约定构建的,原因我无法解释。没什么大不了的,除了它也是用MinGW和MinGW和Visual C ++构建的,不同意__stdcall的含义。有关详细信息,请参阅here,但基本上MinGW会将名称变为Function@n,而MSVC会将其变为_Function@n。这是一个不在你的DLL中使用__stdcall的好理由......

切换到__stdcall对于以前的维护者来说非常重要,因为当他们切换到它时,他们碰到了一个主要的版本号(因为它破坏了ABI的兼容性)并且我不愿意再次碰到它以切换回__cdecl

基本上,我需要说服MSVC像MinGW那样装饰DLL中的符号,或者使用某种别名,或者只是更改名称。我不关心哪个,因为套件中的其他软件可以很容易地重建以调用DLL但是需要它 - 它是我担心的现有软件。

我怀疑我需要一个.DEF文件,但我不愿手工制作。有几十个导出的函数。

所以这就是问题 - 有没有自动化或大多数自动化的方法来做到这一点?

1 个答案:

答案 0 :(得分:0)

我能够编写一个简单的Python脚本来执行此操作。我不知道是否有更简单的方法,但这对我有用

您需要pexports(从here链接),然后您可以使用pexports mylib.dll > mylib-stock.def在您的DLL上运行它。然后使用fixdefs.py mylib-stock.def mylib.def运行此Python脚本,并在构建库时包含该脚本。似乎工作正常。你会得到一个像这样的文件:

_Function@n
Function@n=_Function@n

脚本:

#!/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))