




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、提到腳本,腦海里馬上閃過一大堆:Python,Perl,Ruby,PHP,JS,VBS,LUA。 不過你有沒聽說過,用經(jīng)典的C+做腳本語言嗎?先不多說,上個圖。(先別糾結(jié)那個function,那僅僅是個宏而已,待會你就明白了)或許你在想這一定是瘋了,用世界上最復(fù)雜的語言做腳本,寫的人累不說,腳本引擎先累壞了。各種復(fù)雜的模板庫,要邊解釋邊運行,得有多強大的虛擬機才撐得住。好吧,那么我們退一步,不強求解釋執(zhí)行,回歸到原始的編譯后執(zhí)行。 不過那還算腳本嗎?編譯速度事實上如今高性能的腳本都是先編譯后運行的,大名鼎鼎的JavaScript V8引擎,號稱速度最快的LUA-J
2、it,以及眾所周知的ActionScript。預(yù)先編譯不僅能大幅提高運行速度,更重要的是能夠提前發(fā)現(xiàn)腳本中顯式的錯誤。但腳本中所謂的編譯,和傳統(tǒng)語言的編譯,還是很大區(qū)別的。腳本的編譯,不過是代碼上的深度優(yōu)化,很快就可以完成。相比復(fù)雜了多的C+來說,似乎是望塵莫及的。提到C+的編譯速度,大家的映象莫過于在VC里按下F5之后,看著輸出框內(nèi)一條一條的“Compiling.”緩緩出現(xiàn)。有時僅僅測試一個微小的修改,也要等上好幾秒的時間。緩慢的編譯速度備受煎熬,以至于簡單的程序往往選擇VB或C#這樣可以快速調(diào)試的語言。對于龐大的MFC程序來說,緩慢的編譯是理所當然的。但簡單的小程序出現(xiàn)過長的編譯時間,那一
3、定是頭文件引用的不合理了。事實上,使用預(yù)處理頭文件的小程序,編譯僅僅是一瞬間的,之后的各種停頓往往是IDE引起的。那么我們就來測試下,不用IDE,僅用純命令編譯個C+小程序。我們使用VC6.0的編譯器:CL.exe為了確保純凈的編譯環(huán)境,我們把CL.exe必須依賴的文件復(fù)制到新建的文件夾里。對于VC6的版本,只要有如下5個文件,就可以完成.cpp到.exe的編譯了。C/C+ code ?12345CL.exe C1XX.DLL C2.DLL MSPDB60.DLL Link.exe打開cmd,設(shè)置好環(huán)境變量,對應(yīng)到VC6的頭目錄和庫目錄C/C+ code ?12SET INCLUDE
4、=C:Program Files (x86)Microsoft Visual StudioVC98Include SET LIB=C:Program Files (x86)Microsoft Visual StudioVC98Lib就可以調(diào)用命令編譯了:C/C+ code ?1cl test.cpp一眨眼的工夫,編譯和鏈接完成,生成了test.exe,一切正常。而這還是在沒有使用預(yù)編譯頭的情況下編譯的。由此可見,即使語言本身很復(fù)雜,但只要用它寫的代碼不復(fù)雜,編譯還是非??斓?。仔細想想也應(yīng)如此。以
5、如今的硬件配置,運行98年的編譯器,編譯一個才幾行代碼的程序,自然是一瞬間的。命令行編譯簡單的C+程序是如此的快速,利用這個優(yōu)勢,繼續(xù)我們的腳本探索。運行環(huán)境如果要寫一個生成100個隨機序列號的小程序,你會使用哪類語言?相比傳統(tǒng)語言要先創(chuàng)建一個工程項目,我們直接在桌面新建個文本文件就可以寫腳本了。雖然用文本編輯器寫代碼沒任何優(yōu)勢,但對于簡單的程序足矣。之后程序交給其他人使用時,腳本優(yōu)勢就淋漓盡致的體現(xiàn)出來了:當他們自己想簡單修改一些邏輯規(guī)則時,只需用記事本打開就可以,而記事本每臺電腦上都有。相反,傳統(tǒng)語言寫的程序,即使有源代碼,用戶想簡單的修改下也無法生效,還需安裝并配置好相應(yīng)的開發(fā)環(huán)境才行,
6、這對不熟悉的人來說頗費周折。所以腳本必須足夠簡單 簡單到用戶只管修改和運行就可以,其他步驟都交給腳本宿主自動完成。如果想用C+寫腳本,那么代碼的編譯和鏈接當然必須是全自動的,這并不復(fù)雜。但僅僅依靠CL.exe等幾個命令還是不夠的,因為在其他的電腦上并沒有相應(yīng)的開發(fā)環(huán)境 Include和Lib文件夾,因此就無法通過編譯和鏈接了。而這些頭文件庫文件,一共多達上千個,全都帶上則有近百兆!顯然,我們的腳本只用到幾個基本功能就可以了,那些復(fù)雜的windows頭文件就沒必要了。事實上,程序的頭文件只是函數(shù)和結(jié)構(gòu)的定義,僅僅用來給編譯器分析而已,最終并不生成實際的
7、指令。所以,我們把常用的頭文件,事先生成一個.pch預(yù)編譯頭文件就可以。以后編譯時,將他對應(yīng)到某個頭文件就可以了,例如stdafx.h。這樣就無需使用任何頭文件了。即使stdafx.h也不在,編譯仍然能通過,因為這一切都打包在.pch里面了。并且大量的頭文件經(jīng)過事先的分析,編譯時就無需再編譯它們了,速度大幅提升。至于Lib文件,里面都是庫函數(shù)的內(nèi)容。除非整個程序不使用任何C運行時庫,那么我們可以不帶上任何lib,但那樣只能寫最基本的代碼了。對于一般的簡單腳本程序,只需幾個必要的lib即可:KERNEL32.LIB,LIBCMT.LIB,LIBCPMT.LIB,OLDNAMES.LIB??偣膊?
8、M多。我們把這幾個lib文件以及.pch文件,放在cl.exe同個目錄下,這樣就無需指定INCLUDE和LIB環(huán)境變量。至此,我們有了一個精簡版的VC6編譯器。通過上述10個文件,我們可以不依賴任何環(huán)境,獨立編譯C+程序了。C/C+ code ?1cl /Yu"stdafx.h" /Fp"MyDLL.pch" test.cpp實際運行現(xiàn)在,我們可以動態(tài)產(chǎn)生C+代碼文件,并且自動編譯的能力了。但是如何將最終的二進制文件與腳本宿主交互呢?由于exe只能運行在獨立的進程里,數(shù)據(jù)交互只能通過匿名管道,要實現(xiàn)回調(diào)什么的非常困難。但若換
9、成dll就可以大顯身手了,不僅運行在同一進程空間內(nèi),更重要的是dll是可以動態(tài)加載卸載的,這一點太符合腳本程序的特性了。并且當某個模塊更新了之后,就可以把先前的模塊釋放掉,加載最新的。而這一切都是動態(tài)的,無需重啟宿主即可完成!而且dll可以導(dǎo)出內(nèi)部的函數(shù),宿主用GetProcAddress()就可以輕松獲得某個函數(shù)地址;至于回調(diào),傳遞一個宿主的函數(shù)指針給腳本就可以了。只要約定好函數(shù)聲明,雙方都可以用最簡單原始的方法互相調(diào)用,甚至共享同一塊內(nèi)存空間。為了讓函數(shù)導(dǎo)出更簡潔,本例中定義了個叫function的宏:C/C+ code ?1#define function exter
10、n "C" _declspec(dllexport) void于是就可以簡單的定義一個導(dǎo)出函數(shù)了:C/C+ code ?1234function Test() / some code here 是不是很有腳本的感覺呢:)語法檢查一個用文本編輯器敲出來的代碼,拼寫錯誤是難免的。所以一個好的腳本引擎,會在運行前做一次全面的語法檢查,事先排除明顯的錯誤,而不是邊解釋邊運行。C+就是將其做到了極限,不僅能查出致命的錯誤,甚至不規(guī)范的代碼也會有
11、警告提示。這是非常值得的,一個小bug浪費的時間,足夠幾萬次編譯了。想要在我們的C+腳本里實現(xiàn)這個功能,其實是非常簡單的。因為在調(diào)用cl.exe編譯時,要是有編譯錯誤就會反饋出來。我們根據(jù)對應(yīng)的錯誤行號,提示用戶就可以了。調(diào)試環(huán)境一個強大的腳本引擎,往往帶有調(diào)試器。雖然編譯器能夠預(yù)先排除一些錯誤,但是邏輯上的錯誤只有在運行時才能出現(xiàn)。對于簡單的腳本程序,這項功能似乎不那么重要。畢竟在調(diào)試狀態(tài)下運行,性能會有所影響。在C+腳本里,我們可以通過宏來擴展調(diào)試功能,決定是否輸出調(diào)試信息。不過對于異常錯誤,處理就比較講究了。由于我們最終運行的是二進制dll模塊,這和普通的腳本有著天壤之別。dll模塊是和
12、宿主共用一個進程的,所以一旦當dll內(nèi)異常觸發(fā)時,整個進程包括宿主一塊進入調(diào)試狀態(tài)了(系統(tǒng)裝有開發(fā)環(huán)境的話)。如果錯誤過于嚴重,會導(dǎo)致整個進程的崩潰。這是個非常值得注意的地方,也是C+作腳本在權(quán)限上的隱患。所以盡可能少用指針特性,使用更安全的代碼,讓代碼風險降到最少。對于致命的錯誤,宿主記錄下dump文件是非常重要的,方便調(diào)試。不過出于簡單,本例的宿主是用VB寫的,也就無法在調(diào)用前使用_try進行SEH捕捉。如果宿主也是C+實現(xiàn)的話,則盡可能捕捉dll內(nèi)的異常。 開發(fā)環(huán)境有別于腳本語言,C+本身就是用于大型程序的開發(fā),所以開發(fā)環(huán)境是非常完善的。但作為一個腳本,往往都是單個的文本文件,
13、而不是一個項目組。任何版本的VC編輯單個cpp文件,和編輯純文本文件幾乎沒有區(qū)別。因此我們事先得建立一個模板項目,將需要編輯的cpp移到此項目內(nèi)開發(fā),這樣才會有下拉框智能提示等功能。不過既然選擇它作為腳本來使用,那就應(yīng)該用來處理一些簡單的,經(jīng)常變更的邏輯事務(wù)。對于復(fù)雜的腳本程序,還不如直接寫在宿主里面了。事實上,“程序”和“腳本”之間從沒一條固定的界限。用純粹的程序也可以寫一個復(fù)雜的游戲故事情節(jié),用純粹的腳本也可以開發(fā)一個大型項目。只不過太過死板,或太過靈活,都會增加額外的工作量。 總結(jié)與其稱之為C+腳本,倒不如說是插件可以根據(jù)需求,動態(tài)產(chǎn)生指令的插件。雖然可以玩轉(zhuǎn)出一些腳本的特征,然而C+終究是門嚴格的語言。相比腳本的靈活性,C+固然更為嚴謹和死板。當然,憑借強大的宏、模版、運算符重載,我們可以充分擴展,為腳本提供豐富多樣的特征和語法糖。當然,它的優(yōu)勢也是顯而易見的:性能超高,交互簡單。并且完全支持C+的特性。事實上,不僅僅是C+,任何一門高級語言都可以當“腳本”使用,只要調(diào)用它們的編譯器即可。如果喜歡C#,或者Java風格,只需稍作修改就可以。 為了簡單演示,本例使用寫了個簡單的宿主程序,包括基本的編譯,鏈接,加載,語法檢查功能。宿主提供了一個叫“Print”的接口,可以輸出字符串。要實現(xiàn)更多接口和擴展
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度餐廳服務(wù)員職業(yè)發(fā)展規(guī)劃與晉升合同
- 二零二五年度汽車美容店市場營銷人員用工合同規(guī)范
- 二零二五年度工傷賠償協(xié)議范本(服裝行業(yè))
- 2025年陽江貨運從業(yè)資格證考試技巧
- 2025年武漢貨運從業(yè)資格證模擬考試試題答案解析
- 2025年萊蕪貨運從業(yè)資格證考試內(nèi)容
- 2025年延邊貨運從業(yè)資格證模擬考試下載
- 年度產(chǎn)品研發(fā)進展報告表
- 五年級六一發(fā)言稿
- 本季度營銷活動詳細規(guī)劃
- 國內(nèi)外材料牌號對照
- 建設(shè)工程施工合同培訓(xùn)PPT(49頁)
- 巴黎盧浮宮介紹PPT模板課件
- 蒂森克虜伯電梯曳引輪鋼絲繩安裝布置
- LY∕T 2780-2016 松皰銹病菌檢疫技術(shù)規(guī)程
- 航空服務(wù)形體訓(xùn)練課程標準
- 項目部安全管理組織機構(gòu)網(wǎng)絡(luò)圖GDAQ20102
- 蘇科版四年級勞動技術(shù)下冊教學計劃
- 電網(wǎng)公司客戶資產(chǎn)接收管理細則
- 干部選拔任用工作報告(一報告兩評議).doc
- 蘇教版四年級下冊數(shù)學第二單元認識多位數(shù)測試卷(含答案)
評論
0/150
提交評論