d的共享库支持
原文
我正在推动D中的共享库支持进入更可用的状态.
方法如下:
构建-betterC共享库,构建依赖如上共享库的完整D可执行文件.不管你对-betterC的感觉如何,在此使用它的原因是,避免我在最初推送过程中遇见的druntime问题.
我没有在Posix上,也没在GDC上测试过.现在我只对窗口支持感兴趣,因为它有最多的平台相关问题,我完全忽略了Optlink(就我而言,这是WONTFIX).
ldc和dmd都可这里工作.但是这两例,你都需要手动生成ModuleInfo块.如下所示:
export extern(C) void _D6dynlib3app12__ModuleInfoZ() {
asm {
naked;
di 0;
di 0x1000;
db 0;
}
}
LDC和DMD都无法配置ModuleInfo生成.GDC有办法可打开和关闭它.
如果删除-betterC,由于重复符号(未导出),在dmd中该块不再工作.LDC编译正常.
在代码基中,我发现因为假装是可见性修改器的导出是链接指令,因此--fvisibility=public是非常有用的.(但是,忽略它,因为它是DIP).
作为代码基的一部分,我正在努力让dub工作.我目前正在等待被openssl[1]的vibe.d回归阻止了的PR.表明应从复制至目标目录的依赖上构建,且不链接dll,而是用他们的导入库.
如果修复它,应使如下工作:
0,在LDC和DMD中,实现打开和关闭ModuleInfo生成的开关(忽略-betterC开关).
1,在DMD中导出ModuleInfo.
2,在DMD中,实现打开导出所有符号的开关.
最后:目前,除非使用-betterC或按非D库对待,DMD不适合共享库.对非-betterC,ldc是可行的.
修复错误时,发现使用MSVC链接器时,当前会破坏包含Unicode符号的共享库.
对非英语用户来说,这是拦路虎.
必须要净化这些符号名,使它们是ASCII.
可惜,在测试套件中有个不完整的测试用例,它只覆盖了可执行文件.
在MSVC链接器中,LDC也遇见的bug(他们像我一样通过禁止测试来解决).
喜悦,通过修复导出ModuleInfo可关闭另一个错误报告.错误
pr这里
我再次尝试解决,在窗口上,不导出ModuleInfo问题.
因为它阻止D可执行文件导入DLL中的D模块,这是个问题.
目前,除了如下,我已成功导出并添加至importedModules成员:
按ModuleInfo**[],而不是ModuleInfo*[]添加.
//dmodule.d ~364
Symbol* isym; ///导入csym的版本
//toobj.d ~190,处理importedModules
import std.algorithm : canFind;
if (mod.ident.toString().canFind("second")) {
if (!mod.isym) {
mod.isym = s.toImport(mod.loc);
outdata(mod.isym);
}
s = mod.isym;
//s.Sflags |= SFLweak;
dtb.xoff(s, 0, TYnptr);
} else {
//弱引用不会从库中拉对象,如果未拉入,则解析为0.不能仅因为导入了模块,就拉入它.
s.Sflags |= SFLweak;
dtb.xoff(s, 0, TYnptr);
}
//导出:
objmod.export_symbol(m.csym, 0);
看起来简单,实际难.
注意:上面代码中,我硬编码为仅应用至"第二"模块,来避免构建druntime.
得到未解析错误,该错误的有趣在,它引用了ldc函数的DllImport符号.在开始运行时时有效地解引用和设置的操作系统链接器的顶部做了额外修补.排除了它只是dmd的限制,而是系统链接器和代码生成器级别的概念问题.
那么这对dmd表明什么呢?好吧,要么从ldc复制方法,要么按需修补.按需修补可能最好,但即在调用importedModules时,在两个地方用额外内存分配来更改druntime.
浙公网安备 33010602011771号