原文
这里有个简单的无需更改动态库或应该动态链接到它的DMD项目中源码的方法.当然,并不能解决潜在的C++调用约定问题(C不存在),但可在有它们时再调查.
我做了个小小的概念证明,它有效.为了具体起见,假设动态库是libx.dll,使用安装了最新MSYS2的(mingw64)gcc构建它,因为这是我需要的所有工具和bash命令行.
假设构建时,DMD项目为可执行文件,并从main.d及other.d及包含使用libx.dll的必要声明的D的header.di接口文件,编译至main.exe.
因为libx.dll是从C源码编译的,而不是从C++编译的,假设暂时没有混杂问题.
要从DMD的main.exe可执行文件动态链接到libx.dll.
在构建main.exe时,DMD需要链接implib(导入库),且可从def文件(模块定义文件)创建此类文件,使用了解DMD所在的MSVC世界的库管理器.
让libx.def为libx.dll的def文件,让libx.lib成为libx.dll的implib文件.
链接libx.dll时,一般由gcc用-Wl,--output-def=libx.def创建def文件.且可用与该mingw64的gcc一起分发的dlltool创建一个implib.
$ dlltool -D libx.dll -d libx.def -l libx.lib -m i386:x86-64
或,可用微软的lib工具:
$ lib -nologo -machine:x64 -def:libx.def -out:libx.lib
现在,构建main.exe时,只需要链接到该导入库,就可工作了.
$ dmd main.d other.d header.di libx.lib
$ ./main #works
现在假设转向C++.如果如上创建导入库,则不会链接main.exe构建,因为impliblibx.lib中的gcc混杂名与DMD提供的MSVC混杂名不匹配.
可修改def文件,并生成一个包含MSVC混杂名的implib,来代替相应的gcc混杂名来解决该问题!
implib包含要链接到的每个名字,及该名所引用函数在动态库中的相应位置.即,libx.lib包含每个gcc混杂名,及相应函数在libx.dll中的位置.
因此,如果用implib的libx.lib中相应的MSVC混杂名替换gcc混杂名,则问题就解决了.
有很多方法可完成!但是,def文件中有个机制这里可完成.
这是由如下命令生成的玩具libx.dll的def文件libx.def.
//命令
g++ -shared libx.o -o libx.dll -Wl,--output-def=libx.def
//`libx.def`
EXPORTS_Z11complicatedi @1
这里_Z11complicatedi@1是int complicated(int)的gcc混杂.可惜,other.d期望按?complicated@@YAHH@Z混杂该函数,因为这是int __cdecl complicated(int)的MSVC混杂,并来自在header.di中的extern(C++)int complicated(int);.
Editing libx.def into
EXPORTScomplicated@@YAHH@Z=_Z11complicatedi @1
生成implib的libx.lib时,按右侧的gcc混杂名替换混杂左侧的MSVC名.如前使用MS的lib工具,并构建main.exe消除了链接错误,就可以了.
但是,虽然如前使用dlltool或llvm-dlltool会产生满足链接器的implib,但运行时生成的main.exe在玩具示例中没有作用,只是返回到提示符,截至2024-02-29没有输出.
对main.exe和libx.dll,可在def文件中机械地生成包含许多替换行的libx.def及libx.lib.或libx.def和libx.lib可在编写DMD项目时使用新符号时动态重建.
使用MS的dumpbin工具可生成文本,从中可提取MSVC混杂符号及解混杂.
因此,如果使用-lib选项来把DMD项目编译为库,以便在链接中断时生成它,则可通过在生成的main.lib上运行dumpbin并撕毁生成的文本来,自动构造用来链接的(解混杂,MSVC混杂)名对表.
类似地,nm工具可用来从libx.dll生成(解混杂,gcc混杂)对的表,并结合libx.def文本,如上例所示,来生成修改后的libx.def和必要的附加限定符.
脚本也可这样,然后运行lib以在构建过程中动态构建导入库.或,如果在D头文件中已有库的绑定,比如header.di,则它可一劳永逸地生成包含未混杂名和MSVC混杂名对,然后用相应的libx.def文件生成与libx.dll一起使用的implib的libx.lib.
这里有很多可能性!
原则上可仅使用nm来制作替换def文件来转储MSVC混杂的二进制文件,因此不需要MS工具来制作它.
我刚刚发现DMD带有MSVC篡改名的dde混杂.exe.
取消它:dde混杂仅根据D混杂名而不是MSVC的方式解混杂.