多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內(nèi)最全IT社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當前位置:首頁 > php開源 > php教程 > TCC研究(2) 把C語言當作腳本,解釋執(zhí)行,并嵌入各類程序

TCC研究(2) 把C語言當作腳本,解釋執(zhí)行,并嵌入各類程序

來源:程序員人生   發(fā)布時間:2015-04-28 08:46:52 閱讀次數(shù):4027次

Tiny C Compiler(簡稱TCC, 或Tiny CC)是世界上最小的C語言編譯器。

TCC有1個突出的特點:就是可以把C語言當作腳本使用。試用記錄以下:


首先,安裝好TCC.   

在Windows下, 下載履行程序: tcc-0.9.26-win32-bin.zip。 解壓到c: cc, 將c: cc添加到PATH目錄中。

測試安裝是不是成功,在命令行窗口中打入命令   tcc -v , 看到TCC版本號即是成功


方式1: 以TCC解釋履行C語言文本

解釋履行,就是不編譯,直接運行。

寫1段C程序,存盤為 hello.c

#include <stdio.h> int main(int argc, char *argv[]) { int i; printf("Hello, world "); for(i=1; i<argc; i++) printf("argv[%d]=%s ", i, argv[i]); }
在命令行窗口,打入命令   tcc -run hello.c

-run 的意思是立即履行

運行結果:

Hello, world


還可以通過命令行,向程序傳入?yún)?shù)

在命令行窗口,打入命令   tcc -run hello.c param1 param2

運行結果(顯示有兩個傳入?yún)?shù)):

Hello, world
argv[1]=param1
argv[2]=param2


方式2: 在Linux下,把C語言程序當作腳本運行,像SH腳本1樣

首先,在Linux下安裝TCC,我用的版本是Ubuntu 14.04

下載TCC源碼,解壓

cd ~

wget  http://download.savannah.gnu.org/releases/tinycc/tcc-0.9.26.tar.bz2

tar  xvf  tcc-0.9.26.tar.bz2

則生成1個子目錄 tcc-0.9.26,進入目錄,編譯它

cd tcc-0.9.26

./configure

make

make install

完成后,輸入命令  tcc -v .  如顯示tcc版本號,表示成功。

用find命令查找1下 tcc 在哪?    find / -name tcc

發(fā)現(xiàn)tcc可履行文件安裝在  /usr/local/bin

寫1段C程序,存盤為 hello.c

#!/usr/local/bin/tcc -run #include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, world "); }
第1行的 #!/usr/local/bin/tcc -run 是告知操作系統(tǒng),這是1個腳本,解釋器是 /usr/local/bin/tcc

修改權限,將hello.c 轉為可履行文件 

   chmod +x hello.c

直接運行hello.c

./hello.c

運行結果:

hello,world

感覺不錯, .c文件直接當腳本


對照1下, 編譯后再履行的情況 ,把hello.c編譯1下:    tcc hello.c   ,  將生成 a.out

運行a.out:  ./a.out

運行結果與腳本履行1樣

由于有第1行的 #!/usr/local/bin/tcc -run, 用gcc編譯hello.c會出錯,用tcc編譯就沒問題


方式3:在程序中嵌入腳本功能,動態(tài)調(diào)用C語言腳本(這是TCC的精華的地方)

嵌入腳本,就是讓你的程序具有腳本功能,而且這個腳本還是C語言的。

tcc目錄下的 exampleslibtcc_test.c是1個示范程序。

我覺得示范程序不通用,因而自己編了1個通用的模塊,兩個文件:   cscript.c, cscript.h

先看 cscript.c,  定義了1個函數(shù)  run_script() 

說明1下: libtcc.h 是 tcc提供的1個頭文件,在tcc目錄下復制過來的

#include <stdlib.h> #include "libtcc.h" //TCC提供的頭文件 /* 運行1個腳本, 啟動腳本中指定的函數(shù),返回該函數(shù)的運行結果值 * 腳本中的啟動函數(shù)原型必須為: int func(int param) * program是腳本全部內(nèi)容, function_name是啟動函數(shù)名稱,param是傳遞給函數(shù)的參數(shù) * tcc_path用于指定tcc所在目錄,tcc_path設為時NULL表示不指定tcc目錄 */ int run_script(char *program, char *function_name, int param, char *tcc_path) { TCCState *s; //TCC編譯引擎 int (*func)(int); //1個函數(shù)指針, 函數(shù)原型為: int func(int param) int result; //運行結果 s = tcc_new(); //初始化TCC編譯引擎 if (!s) return ⑴; //初始化失敗 //tcc_path指定tcc所在的目錄 if (tcc_path!=NULL) tcc_set_lib_path(s, tcc_path); //指明編譯結果寫入內(nèi)存,而不是存為文件 tcc_set_output_type(s, TCC_OUTPUT_MEMORY); //如果編譯失敗,則退出 if (tcc_compile_string(s, program) == ⑴) { tcc_delete(s); return ⑵; } //如果程序重定位失敗,退出 if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0) { tcc_delete(s); return ⑶; } //尋覓名為function_name的入口函數(shù) func = tcc_get_symbol(s, function_name); if (!func) { //找不到入口函數(shù),則退出 tcc_delete(s); return ⑷; } //運行入口函數(shù),取得運行結果 result = func(param); //結束TCC編譯引擎 tcc_delete(s); return result; }

再看  cscript.h ,不過聲明了1下run_script()這個函數(shù)。

#ifndef __CSCRIPT_H__ #define __CSCRIPT_H__ #ifdef __cplusplus extern "C" { #endif /** 運行1個腳本, 啟動腳本中指定的函數(shù),返回該函數(shù)的運行結果值 * 腳本中的啟動函數(shù)原型必須為: int func(int param) * programe是腳本程序, function_name是啟動函數(shù),param是傳遞給函數(shù)的參數(shù) * tcc_path用于指定tcc所在目錄,tcc_path設為NULL時表示不指定tcc目錄 */ extern int run_script(char *program, char *function_name, int param, char *tcc_path); #ifdef __cplusplus } #endif #endif

好了, 編1個主程序,使用通用模塊中的run_script()函數(shù),每次通過命令行指定腳本文件,讀出并運行。

假定主程序名為 cscript.exe

運行命令為:   cscript   <script_file>

主程序以下,存盤為 main.c

#include <stdio.h> #include <stdlib.h> #include "cscript.h" //通用模塊頭文件 int main(int argc, char *argv[]) { char *program = NULL; //腳本內(nèi)容 char *function_name = "script_main"; //啟動函數(shù)名為script_main int param = 888; //傳入?yún)?shù) char *tcc_path = NULL; int file_size; int result; //返回結果 FILE *fp; if (argc<=1) { printf("Usage: cscript <script_file> "); return ⑴; } //第1個命令行參數(shù)是腳本文件名,打開它 if ((fp=fopen(argv[1],"rb"))==NULL) { printf("Error open file %s ", argv[1]); return ⑴; } //測出文件長度 fseek(fp, 0L, SEEK_END); file_size = ftell(fp); //申請1個內(nèi)存用于寄存文件內(nèi)容 program = (char *)malloc(file_size+1); if (program==NULL) return ⑴; //將文件內(nèi)容全部讀入到 program中 fseek(fp, 0L, SEEK_SET); if (fread(program, file_size, 1, fp)>0) { program[file_size]=0; result = run_script(program, function_name, param, tcc_path);//運行 printf("result = %d ", result); } free(program); fclose(fp); }
這個程序比較簡單,不過是從命令行第1個參數(shù)指定的文件中,讀出內(nèi)容,當作腳本履行。

腳本中需要指定1個啟動函數(shù),這個函數(shù)不是main(), 而是 int script_main(int param)

編譯主程序(main.c 和 cscript.c), 假定tcc安裝在c: cc目錄下

tcc -llibtcc -Lc: cc main.c cscript.c -o cscript.exe

-llibtcc 表示鏈接 libtcc庫 (大小寫不要寫錯)

-Lc: cc 指定tcc目錄(大小寫不要寫錯)

-o cscript.exe 指定生成exe文件為 cscript.exe

編譯成功,沒有任何提示。目錄下生成 cscript.exe


好了,寫1個腳本(內(nèi)容以下),存盤為 test1.txt

#include <stdio.h> int script_main(int param) { printf("it's in script main, param =%d ", param); return param; }

用剛才生成的 cscript.exe 直接運行 test1.txt

打入命令   cscript  test1.txt

運行結果:

it's in script main, param =888
result = 888

成功!!

這1次,我們不是使用tcc去運行腳本,而是采取剛才自己寫的 cscript.exe程序去運行腳本。讓自己的程序具有了腳本功能。

從TCC提供的example上看,TCC可以支持標準C, windows API調(diào)用,Linux動態(tài)庫調(diào)用等,就是說,用腳本寫系統(tǒng)程序、GUI,甚么都行。 

相當于遠程分發(fā)程序。

如何利用,看想像力了。比如說: 程序從網(wǎng)站下載1個文本,運行,生成1個GUI,產(chǎn)生1個小人在桌面上跑來跑去……

再比如:大數(shù)據(jù)運算,100臺計算機聯(lián)網(wǎng),某臺機分發(fā)1個腳本,各機本地運算,返回結果給主機匯總,就是大數(shù)據(jù)的map-reduce算法嘛。

心有多遠,就有多遠

TCC就是強!  




生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 性欧美videofree另类17 | 亚洲欧洲精品成人久久曰 | 欧美激情性xxxxx | 欧美色爽 | 亚洲欧美日韩国产综合高清 | 成人免费淫片免费观看 | 性欧美极品xxxx欧美一区二区 | 久久2| 动漫精品成人免费网站 | 97麻豆精品国产自产在线观看 | 亚洲人成伊人成综合网久久久 | 国产精品亚洲午夜一区二区三区 | 国产精品久久久久久久久久免费 | 欧美综合图区亚欧综合图区 | 欧美性高清极品猛交 | 国产亚洲欧美另类久久久 | a天堂v| 亚洲精品一区二区三区在线看 | 亚洲国产精品免费 | 福利影院第一页 | 国产精品成人久久久久久久 | 中文字幕最新中文字幕中文字幕 | 中文字幕欧美激情 | 日本在线视频一区二区三区 | 一级秋霞理论 | 广西毛片| 一本到亚洲网 | 中文字幕在线视频观看 | 亚洲 图片 小说 欧美 另类 | 亚洲欧洲国产视频 | 色综合久久久久久久久久久 | 欧欧美18videosex性哦欧美美 | 亚洲成a人片 | 狂野黑人性猛交xxxxxx | 欧美性猛交xxxx乱大交丰满 | 武则天a级在线观看 | 91在线一区二区 | 五月婷婷在线视频 | 日本精品一区二区三本中文 | 中国日本高清免费视频网 | 亚洲欧美综合一区二区三区四区 |