原文
导入用'-betterC'单独编译的XYZ模块,会有因为缺少应由XYZ模块定义的叫__ModuleInfo的符号的链接器错误.
一种补救方法是在XYZ中定义此值:

extern(C) __gshared ModuleInfo _D3dmd7backend7ptrntab12__ModuleInfoZ;导入模块会依次添加所有导入模块的引用,参见.object.ModuleInfo中定义的importedModules属性的定义.
这真是问题吗?为啥要用-betterC编译D库,然后在D程序中使用它?
一个用例是dmd编译自身.
一般,想在D中构建可同时使用C和D的库.
$ dmd -betterC -lib mylib1.d mylib2.d
$ dmd -I. mylib1 myexe.d -main
module myexe;
import mylib2;
module mylib1;
static this() {}
module mylib2;
import mylib1;为什么'mylib1'有模块构造器?,'-betterC'不应拒绝它吗?
有人创造性地在更好的C模式下,用'pragma(crt_constructor)'制作了模块构造器.
不是只对'shared static this'吗?
:dmd -betterC -lib mylib1.d mylib2.d这编译mylib1.d和mylib2.d,并创建包含两个文件目标代码的mylib.lib库文件.
:dmd -I. mylib1 myexe.d -main这会把mylib1.d和myexe.d编译在一起,形成mylib1.exe的可执行文件.因为命令行中没有给出,它无法从mylib2.d中找到内容.这不是编译器错误.
我想应,创建放入mylib1.d和mylib2.d编译版本的mylib1.obj:
dmd -betterC mylib1.d mylib2.d而,
dmd -I. myexe.d mylib1.obj -main编译myexe.d并链接到mylib1.obj,来创建叫myexe.exe的可执行文件.或至少这样做,但给出:
myexe.obj(myexe)
Error 42: Symbol Undefined __D6mylib212__ModuleInfoZ因为-betterC抑制生成ModuleInfo,而myexe.d却期望它.这是编译器错误,或至少是编译器问题.
如果以下至少有一个为真,模块就会产生ModuleInfo:1.它导入生成ModuleInfo模块.2.它有个静态构造器3.它有静态析构器4.它有单元测试声明
但如果启用了-betterC,则会禁止生成,本问题,是由于有静态构造器的问题.Iain的想法是正确的.在-betterC模式下,解决方法是:1.使用以下来自动注解静态构造器:
pragma(crt_constructor) extern (C)2.对静态析构器同样3.对(1)和(2)不设置'needmoduleinfo'.
这会用C运行时库机制运行构造器和析构器.缺点是按链接器看到的目标文件顺序,而不是深度优先层次顺序构造和析构.Mathias的建议很好.在'static this()'上给出错误,并仅在'shared static this()'上工作.
mylib1.d中有个静态构造器.何时构造?
在C代码中,C运行时按它们在链接器中顺序来处理.
在D代码中,D启动代码,会在C运行时初化*之后*按深度优先级处理.两者是不同的,且是不可调和的(尽管大多数静态构造器可能不关心顺序,但不能依赖它).myexe.d无法知道它正在导入更好C模块,因此它无法正确处理构造.
因此,提出另一种方法.mylib1.d只需选择是C构造还是D构造.C构造将是:
pragma(crt_constructor) extern (C) static this() {... }而D构造:
static this() {... }myexe.d在看到D静态构造器时,需要来自mylib1.d的ModuleInfo.编译器在用-betterC编译mylib1.d时,且看到D静态构造器时,则可为该静态构造器创建ModuleInfo.
为更好C和D程序,创建更好C库,用:
pragma(crt_constructor) extern (C) static this() {... }D模块构造器当然不应在betterC代码中工作.它们可抛死码警告,因此不需要生成ModuleInfo(这应该很容易解决).这避免未来意外.
然而,根本问题是按需付费运行时,在-betterC中,需要ModuleInfo时,不能按需付费的打开它.
现在无法打开生成ModuleInfo,因为DllImport不完整(实现难).如果现在开启它,exe与带D的dll运行时,会有段错误.
应该先解决DllImport问题,然后用此代码作为测试用例来验证,是否确实修复它,而不是先修复本漏洞.
本例中,ModuleInfo是D运行时如何运行静态构造器.用betterC编译的程序只能与对ModuleInfo一无所知的C运行时库链接.
问题是编写用betterC编译的库,并与betterC程序或D程序链接.
简单关闭生成ModuleInfo,表明betterC的库不运行它的静态构造器.
由于导入betterC模块的D程序不知道它们是否是betterC模块,因此betterC模块选择如何静态构造.
即,更好C模块应用以下代码来运行其静态构造:
pragma(crt_constructor) extern (C) void doMyStaticConstruction() {... }如果更好C只与D主连接,它应该:
static this() {... }但不应同时执行这两个操作,因为如果同Dmain链接,则静态构造了两次.
修复该错误报告的改变是,对betterC模块,如果有'static this'构造器就生成ModuleInfo,并在文档中添加这些指令.导出DLL是个正交问题.
这不应是自动的.-betterC是一个开关的集合.其中之一是关闭生成ModuleInfo.这是它在LDC和GDC中的工作方式.
它需要通过开关选入.否则,可能会有意外.
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站栏目:d导入更好C的链接器错误-创新互联
网页路径:http://www.jxjierui.cn/article/epecd.html


咨询
建站咨询
