关于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;
}
参考文档
时间: 2024-10-14 03:59:55