日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

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

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

來源:程序員人生   發布時間:2015-04-28 08:46:52 閱讀次數:4032次

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


還可以通過命令行,向程序傳入參數

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

運行結果(顯示有兩個傳入參數):

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

發現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 是告知操作系統,這是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:在程序中嵌入腳本功能,動態調用C語言腳本(這是TCC的精華的地方)

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

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

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

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

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

#include <stdlib.h> #include "libtcc.h" //TCC提供的頭文件 /* 運行1個腳本, 啟動腳本中指定的函數,返回該函數的運行結果值 * 腳本中的啟動函數原型必須為: int func(int param) * program是腳本全部內容, function_name是啟動函數名稱,param是傳遞給函數的參數 * 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個函數指針, 函數原型為: 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); //指明編譯結果寫入內存,而不是存為文件 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的入口函數 func = tcc_get_symbol(s, function_name); if (!func) { //找不到入口函數,則退出 tcc_delete(s); return ⑷; } //運行入口函數,取得運行結果 result = func(param); //結束TCC編譯引擎 tcc_delete(s); return result; }

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

#ifndef __CSCRIPT_H__ #define __CSCRIPT_H__ #ifdef __cplusplus extern "C" { #endif /** 運行1個腳本, 啟動腳本中指定的函數,返回該函數的運行結果值 * 腳本中的啟動函數原型必須為: int func(int param) * programe是腳本程序, function_name是啟動函數,param是傳遞給函數的參數 * 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()函數,每次通過命令行指定腳本文件,讀出并運行。

假定主程序名為 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; //腳本內容 char *function_name = "script_main"; //啟動函數名為script_main int param = 888; //傳入參數 char *tcc_path = NULL; int file_size; int result; //返回結果 FILE *fp; if (argc<=1) { printf("Usage: cscript <script_file> "); return ⑴; } //第1個命令行參數是腳本文件名,打開它 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個內存用于寄存文件內容 program = (char *)malloc(file_size+1); if (program==NULL) return ⑴; //將文件內容全部讀入到 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個參數指定的文件中,讀出內容,當作腳本履行。

腳本中需要指定1個啟動函數,這個函數不是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個腳本(內容以下),存盤為 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調用,Linux動態庫調用等,就是說,用腳本寫系統程序、GUI,甚么都行。 

相當于遠程分發程序。

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

再比如:大數據運算,100臺計算機聯網,某臺機分發1個腳本,各機本地運算,返回結果給主機匯總,就是大數據的map-reduce算法嘛。

心有多遠,就有多遠

TCC就是強!  




生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 色婷婷香蕉在线一区二区 | 国产高清在线视频 | 国产在线v| 久久国产精品毛片 | 欧美激情中文字幕 | 日韩激情一区 | www.99热.com| 91嫩草精品 | 精品色综合| 久久久久久免费精品一区二区三区 | 欧美在线色图 | 亚洲福利一区二区 | 欧美性猛交xxxx | 亚洲一区二区日韩 | 国产精品久久久久久久久久久久久 | 黄动漫在线观看 | 国产精品一区二区三区在线 | 日韩中文字幕第一页 | 麻豆传媒视频 | 日韩一区二区免费视频 | 一区二区三区国产在线 | 亚洲网站在线看 | 黄色高清视频 | 又爽又黄的视频 | 成人国产在线观看 | 国产精品一区二区三区在线 | 久久人人爽爽人人爽人人片av | 亚洲一区在线免费 | 天天综合网日日夜夜 | 欧美区一 | 日韩中文字幕一区二区三区 | 波多野结衣乳巨码无在线观看 | 中文字幕国产日韩 | 五月天久久久 | 国产在线二区 | 伦视频 | 在线观看视频一区 | 国产精品久久久久久久久 | 成人一二三区 | 视频在线亚洲 | 久久视频一区二区 |