原文
这里有个简单的无需
更改动态库
或应该动态链接
到它的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
的方式解混杂
.