新聞中心
原文
導(dǎo)入用'-betterC'
單獨(dú)編譯的XYZ
模塊,會(huì)有因?yàn)槿鄙賾?yīng)由XYZ
模塊定義的叫__ModuleInfo
的符號(hào)的鏈接器錯(cuò)誤
.
一種補(bǔ)救
方法是在XYZ
中定義此值:
extern(C) __gshared ModuleInfo _D3dmd7backend7ptrntab12__ModuleInfoZ;
導(dǎo)入
模塊會(huì)依次
添加所有導(dǎo)入模塊
的引用
,參見.object.ModuleInfo
中定義的importedModules
屬性的定義.
這真是問題嗎?為啥要用-betterC
編譯D庫(kù)
,然后在D程序中
使用它?
一個(gè)用例是dmd
編譯自身
.
一般,想在D中
構(gòu)建可同時(shí)使用C和D
的庫(kù).
$ 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'
有模塊構(gòu)造器?,'-betterC'
不應(yīng)拒絕它嗎?
有人創(chuàng)造性
地在更好的C
模式下,用'pragma(crt_constructor)'
制作了模塊構(gòu)造器
.
不是只對(duì)'shared static this'
嗎?
:dmd -betterC -lib mylib1.d mylib2.d
這編譯mylib1.d
和mylib2.d
,并創(chuàng)建包含兩個(gè)
文件目標(biāo)代碼的mylib.lib
庫(kù)文件.
:dmd -I. mylib1 myexe.d -main
這會(huì)把mylib1.d
和myexe.d
編譯在一起,形成mylib1.exe
的可執(zhí)行
文件.因?yàn)?code>命令行中沒有給出,它無法從mylib2.d
中找到內(nèi)容.這不是編譯器
錯(cuò)誤.
我想應(yīng),創(chuàng)建放入mylib1.d
和mylib2.d
編譯版本的mylib1.obj
:
dmd -betterC mylib1.d mylib2.d
而,
dmd -I. myexe.d mylib1.obj -main
編譯myexe.d
并鏈接到mylib1.obj
,來創(chuàng)建叫myexe.exe
的可執(zhí)行文件.或至少這樣做,但給出:
myexe.obj(myexe)
Error 42: Symbol Undefined __D6mylib212__ModuleInfoZ
因?yàn)?code>-betterC抑制生成ModuleInfo
,而myexe.d
卻期望它.這是編譯器
錯(cuò)誤,或至少是編譯器
問題.
如果以下至少有一個(gè)為真
,模塊
就會(huì)產(chǎn)生ModuleInfo
:1
.它導(dǎo)入生成ModuleInfo
模塊.2
.它有個(gè)靜態(tài)構(gòu)造器
3
.它有靜態(tài)析構(gòu)器
4
.它有單元測(cè)試
聲明
但如果啟用了-betterC
,則會(huì)禁止
生成,本問題,是由于有靜態(tài)構(gòu)造器
的問題.Iain
的想法是正確
的.在-betterC
模式下,解決方法是:1
.使用以下來自動(dòng)注解靜態(tài)構(gòu)造器
:
pragma(crt_constructor) extern (C)
2
.對(duì)靜態(tài)析構(gòu)器
同樣3
.對(duì)(1)
和(2)
不設(shè)置'needmoduleinfo'
.
這會(huì)用C運(yùn)行時(shí)庫(kù)
機(jī)制運(yùn)行構(gòu)造器和析構(gòu)器
.缺點(diǎn)
是按鏈接器
看到的目標(biāo)
文件順序,而不是深度優(yōu)先
層次順序構(gòu)造和析構(gòu)
.Mathias
的建議很好.在'static this()'
上給出錯(cuò)誤,并僅在'shared static this()'
上工作.
mylib1.d
中有個(gè)靜態(tài)構(gòu)造器
.何時(shí)構(gòu)造?
在C代碼中,C
運(yùn)行時(shí)按它們?cè)?code>鏈接器中順序來處理.
在D代碼中,D
啟動(dòng)代碼,會(huì)在C運(yùn)行時(shí)
初化*之后*
按深度
優(yōu)先級(jí)處理.兩者
是不同的,且是不可調(diào)和
的(盡管大多數(shù)靜態(tài)構(gòu)造器
可能不關(guān)心順序,但不能依賴它).myexe.d
無法知道它正在導(dǎo)入更好C
模塊,因此它無法正確處理構(gòu)造.
因此,提出另一種方法.mylib1.d
只需選擇是C構(gòu)造
還是D構(gòu)造
.C構(gòu)造
將是:
pragma(crt_constructor) extern (C) static this() {... }
而D構(gòu)造
:
static this() {... }
myexe.d
在看到D靜態(tài)構(gòu)造器
時(shí),需要來自mylib1.d
的ModuleInfo
.編譯器在用-betterC
編譯mylib1.d
時(shí),且看到D靜態(tài)構(gòu)造器
時(shí),則可為該靜態(tài)構(gòu)造器
創(chuàng)建ModuleInfo
.
為更好C和D
程序,創(chuàng)建更好C
庫(kù),用:
pragma(crt_constructor) extern (C) static this() {... }
D模塊構(gòu)造器
當(dāng)然不應(yīng)在betterC代碼
中工作.它們可拋死碼
警告,因此不需要生成ModuleInfo
(這應(yīng)該很容易解決).這避免未來
意外.
然而,根本
問題是按需
付費(fèi)運(yùn)行時(shí)
,在-betterC
中,需要ModuleInfo
時(shí),不能按需付費(fèi)的打開
它.
現(xiàn)在無法打開生成ModuleInfo
,因?yàn)?code>DllImport不完整(實(shí)現(xiàn)難).如果現(xiàn)在開啟
它,exe
與帶D
的dll
運(yùn)行時(shí),會(huì)有段錯(cuò)誤
.
應(yīng)該先解決DllImport
問題,然后用此代碼
作為測(cè)試用例
來驗(yàn)證
,是否確實(shí)修復(fù)
它,而不是先修復(fù)本漏洞
.
本例中,ModuleInfo
是D運(yùn)行時(shí)
如何運(yùn)行靜態(tài)構(gòu)造器
.用betterC
編譯的程序只能與對(duì)ModuleInfo
一無所知的C運(yùn)行時(shí)
庫(kù)鏈接.
問題是編寫用betterC
編譯的庫(kù),并與betterC
程序或D程序
鏈接.
簡(jiǎn)單關(guān)閉生成ModuleInfo
,表明betterC
的庫(kù)不運(yùn)行
它的靜態(tài)構(gòu)造器
.
由于導(dǎo)入betterC
模塊的D程序
不知道它們是否是betterC
模塊,因此betterC
模塊選擇如何靜態(tài)
構(gòu)造.
即,更好C
模塊應(yīng)用以下
代碼來運(yùn)行其靜態(tài)構(gòu)造
:
pragma(crt_constructor) extern (C) void doMyStaticConstruction() {... }
如果更好C
只與D主
連接,它應(yīng)該:
static this() {... }
但不應(yīng)同時(shí)執(zhí)行這兩個(gè)
操作,因?yàn)槿绻?code>Dmain鏈接,則靜態(tài)
構(gòu)造了兩次.
修復(fù)該錯(cuò)誤報(bào)告的改變是,對(duì)betterC
模塊,如果有'static this'
構(gòu)造器就生成ModuleInfo
,并在文檔
中添加這些指令
.導(dǎo)出DLL
是個(gè)正交
問題.
這不應(yīng)
是自動(dòng)的.-betterC
是一個(gè)開關(guān)
的集合.其中之一是關(guān)閉生成ModuleInfo
.這是它在LDC
和GDC
中的工作
方式.
它需要通過開關(guān)
選入.否則,可能會(huì)有意外
.
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
當(dāng)前標(biāo)題:d導(dǎo)入更好C的鏈接器錯(cuò)誤-創(chuàng)新互聯(lián)
文章出自:http://www.dlmjj.cn/article/epecd.html