libtcc源码分析(一)概览
关于libtcc
.... libtcc的源码仓库:libtcc
libtcc是一个微型的C编译器,它可以将C源码直接编译成机器码,并且通过libtcc提供的接口函数,在宿主程序里可以很方便的获取到libtcc编译后的函数或变量地址,这样相比其他脚本语言,libtcc就具有了以下的特点:
- 脚本完全使用c语言编写,对大多数用c语言入门的人来说,几乎没有任何学习成本,但是同样,处理字符串会变得和c一样麻烦
- 速度,libtcc是直接将源码文件(或者可以说脚本文件)直接编译成机器码的,在编译一次后,再执行脚本就会和Native Code一样快
- 可以很方便的使用几乎所有的c动态链接库
- 使用
tcc_add_symbol函数可以将宿主程序的变量或函数暴漏给libtcc,使用tcc_get_symbol函数可以将脚本编译后的变量或函数暴漏给宿主程序;在libtcc和宿主程序中使用暴漏处理的符号和使用动态链接库一样方便。
libtcc存在的问题:
- libtcc不可以在多线程环境下使用
- 不可以同时使用多个TccState(源码内用到了大量的全局变量)
- 其他bug见libtcc源码包中的TODO文件
使用libtcc
编译
在windows下直接运行win32/build-tcc.bat即可
使用
#include <stdio.h>#include <stdlib.h>#define PAUSE system("pause")#include "../tinycc/libtcc.h"const char szCode[] = "\n"//"//#define MACRO(a, b c) (a+b+c)\n" ///bug1//"double array[10][20];""double add(double a, long b)\n""{\n"" return a+b;\n""}\n";typedef int (*f_iii)(int, int);void error_in_tcc(void *opaque, const char *str){printf(__FUNCTION__": %s\n", str);}int main(){int nRet = 0;TCCState* s1 = tcc_new();tcc_set_error_func(s1, NULL, error_in_tcc);tcc_add_library_path(s1, "E:\\learn\\libtcc\\tinycc\\win32\\lib");//tcc_define_symbol(s1, "MACRO1(a, b)", "b ## a");//tcc_define_symbol(s1, "MACRO0(a, b c)", "(a+b+c)");//tcc_set_output_type(s1, TCC_OUTPUT_MEMORY);nRet = tcc_compile_string(s1, szCode);if (nRet == -1){printf("compile failed!\n");PAUSE;return nRet;}tcc_relocate(s1, TCC_RELOCATE_AUTO);f_iii f = (f_iii)tcc_get_symbol(s1, "add");if (f == NULL){printf("find symbol failed\n");PAUSE;return nRet;}int c = f(10, 20);printf("c = %d\n", c);PAUSE;return 0;}
参考文档
文章来自:http://www.cnblogs.com/fook-ms/p/4271188.html