Tiny C Compiler 嵌入式使用幫助Lua這種東西大家肯定不陌生了,要說這類的嵌入式腳本語言對寫程序來說,確實(shí)會(huì)方便不少.但是lua有幾個(gè)缺點(diǎn)不得不提. 1.lua的語法很怪異,這對于習(xí)慣了腳本開發(fā)的人員也許沒什么,但是對于一個(gè)ASM和C++的程序員無疑的很痛苦的. 2.lua的執(zhí)行速度很慢,極端的情況下,可能達(dá)到同類二進(jìn)制執(zhí)行速度的及百分之一.基本上不能用來代替主程序做大計(jì)算量的工作. 我之前也是用lua,痛苦不言而喻,后來在有花的提醒下,發(fā)現(xiàn)了這么一個(gè)代替lua的好東西--Tiny C Compiler. TCC的優(yōu)點(diǎn): 1.她是一個(gè)完全符合ISOC99的規(guī)范的C語言編譯器.用在嵌入式腳本上,對于C程序員,基本沒有障礙. 2.她是直接編譯化的嵌入式腳本,只要事先編譯了腳本,執(zhí)行的時(shí)候?qū)τ谛视绊懳⒑跗湮? 3.由于她是個(gè)編譯器,所以所有的windows函數(shù),C運(yùn)行庫函數(shù),甚至你可以找到的任何DLL,LIB都可以被她用來作為擴(kuò)充函數(shù). 有這么多有點(diǎn)當(dāng)然是好的,但是很不幸,這東西的資料實(shí)在少的可憐,那干巴巴的一點(diǎn)點(diǎn)文檔是專門說編譯器的,對于嵌入式上的文檔幾乎找不到(google搜索tcc_set_lib_path這類函數(shù)名,結(jié)果居然是0,可見其保密性做的多好.-_-).唯一的途徑就是閱讀源代碼摸索出其用途. 好在關(guān)于怎么將tcc用在嵌入式上的方法,還是很簡單的,不花多少時(shí)間,就能搞定,為了更多的人不再重復(fù)的勞動(dòng),我寫了這么一篇文章.我用的是0.9.25版本,以下默認(rèn)為這個(gè)版本. ////////////////////////////////////////////////////////////////////////////////////////////////// 首先,tcc是可以直接混在工程中編譯的.參考源代碼中的那份"libtcc_test.c"文件,這里說一下編譯方法: 1.include了TCC源碼目錄下的libtcc.h文件. 2.在工程中添加config.h頭文件,內(nèi)容如下: #define TCC_VERSION "0.9.25" 3.調(diào)用tcc_set_lib_path函數(shù)設(shè)置tcc目錄(這點(diǎn)下面代碼中有詳細(xì)說明). 4.tcc_delete(s);必須在func之后調(diào)用.(這點(diǎn)下面代碼中有詳細(xì)說明) 注意:如果你的Tcc腳本中,使用了運(yùn)行庫.記得把工程設(shè)置為ASCII,可能因?yàn)門CC不支持unicode,如果你的工程是Unicode,在Tcc獲取運(yùn)行庫函數(shù)指針的時(shí)候,將獲取不到.(或許還有其他辦法,我沒再琢磨了) ////////////////////////////////////////////////////////////////////////////////////////////////// 然后.其實(shí)大多數(shù)人用的是下面這些: 直接參與編譯的方法很別扭,或者你的工程是Unicode的,那可以采用獨(dú)立編譯成Dll(關(guān)于獨(dú)立編譯的方法和上面直接參與工程編譯的差不多,就不累述了,我已經(jīng)獨(dú)立編譯出了一個(gè)包提供給大家),然后動(dòng)態(tài)鏈接的方式使用Tcc,方法如下: 1.下載我提供的Tcc系統(tǒng)包(在我的網(wǎng)絡(luò)硬盤,blog首頁有)--libtcc.rar 2.將代碼解壓縮到指定的目錄(下面例子中比如說是"Z:\\tcc"目錄). 3.將包中的.libtcc_zv.dll,拷貝到你的程序當(dāng)前目錄(或者系統(tǒng)目錄) 4.編譯如下代碼(wind32-console工程). #include <stdio.h> //這是tcc的連接目錄 //這是打算加入到TCC中的代碼 //這是TCC腳本(姑且算作腳本吧.lua看習(xí)慣了.) int main(int argc, char *argv[]) //加入Tcc連接目錄 //設(shè)置輸出模式為內(nèi)存 //編譯代碼(也就是編譯腳本成可執(zhí)行文件) //將exe中的add函數(shù)的符號(hào)加入到編譯后的腳本中 //重定位代碼中的符號(hào),并輸出到用戶指定內(nèi)存中 //獲取tcc腳本中的一個(gè)函數(shù)符號(hào) //執(zhí)行該函數(shù) //注意,原tcc例子中,這個(gè)delete是放在func之上的 //釋放重定位之后存放的內(nèi)存. return 0; *** VC6編譯的時(shí)候,TCC的頭文件中出現(xiàn)long long定義錯(cuò)誤,改為__int64即可.2003之后版本的VC沒有這個(gè)問題. |
|
|