打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
TCC(Tiny C Compiler)用C语言当脚本例子

        今天在我的C代码里面使用tcc当脚本,感觉比lua还爽, lua已经够小巧够精制了, Tiny C Compiler 更小, 速度也比lua要快, 关键是还能直接传指针参数或指针的返回值,就和C的函数调用一样方便,用TCC的好处是,我们可以把不变的代码用C来实现,把经常要改变的逻辑等用TCC来实现,这样以后修改逻辑相关的东西就不需要重新编译程序,用TCC最方便的地方就是直接把指针当参数和返回值在脚本和宿主程序之间传来传去。


下面是官方源代码里的一个例子 :

  1. /* 
  2.  * Simple Test program for libtcc 
  3.  * 
  4.  * libtcc can be useful to use tcc as a "backend" for a code generator. 
  5.  */  
  6. #include <stdlib.h>   
  7. #include <stdio.h>   
  8. #include <string.h>   
  9.   
  10. #include "libtcc.h"   
  11.   
  12. /* this function is called by the generated code */  
  13. int add(int a, int b)  
  14. {  
  15.     return a + b;  
  16. }  
  17.   
  18. char my_program[] =  
  19. "int fib(int n)\n"  
  20. "{\n"  
  21. "    if (n <= 2)\n"  
  22. "        return 1;\n"  
  23. "    else\n"  
  24. "        return fib(n-1) + fib(n-2);\n"  
  25. "}\n"  
  26. "\n"  
  27. "int foo(int n)\n"  
  28. "{\n"  
  29. "    printf(\"Hello World!\\n\");\n"  
  30. "    printf(\"fib(%d) = %d\\n\", n, fib(n));\n"  
  31. "    printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"  
  32. "    return 0;\n"  
  33. "}\n";  
  34.   
  35. int main(int argc, char **argv)  
  36. {  
  37.     TCCState *s;  
  38.     int (*func)(int);  
  39.   
  40.     s = tcc_new();  
  41.     if (!s) {  
  42.         fprintf(stderr, "Could not create tcc state\n");  
  43.         exit(1);  
  44.     }  
  45.   
  46.     /* if tcclib.h and libtcc1.a are not installed, where can we find them */  
  47.     if (argc == 2 && !memcmp(argv[1], "lib_path=",9))  
  48.         tcc_set_lib_path(s, argv[1]+9);  
  49.   
  50.     /* MUST BE CALLED before any compilation */  
  51.     tcc_set_output_type(s, TCC_OUTPUT_MEMORY);  
  52.   
  53.     if (tcc_compile_string(s, my_program) == -1)  
  54.         return 1;  
  55.   
  56.     /* as a test, we add a symbol that the compiled program can use. 
  57.        You may also open a dll with tcc_add_dll() and use symbols from that */  
  58.     tcc_add_symbol(s, "add", add);  
  59.   
  60.     /* relocate the code */  
  61.     if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)  
  62.         return 1;  
  63.   
  64.     /* get entry symbol */  
  65.     func = tcc_get_symbol(s, "foo");  
  66.     if (!func)  
  67.         return 1;  
  68.   
  69.     /* run the code */  
  70.     func(32);  
  71.   
  72.     /* delete the state */  
  73.     tcc_delete(s);  
  74.   
  75.     return 0;  
  76. }  

 

下面的代码是我在自己的程序里面使用的例子

  1.      
  2.   
  3.     int offset = 0;  
  4.     MatchResult_t Res;  
  5.     memset (&Res, 0, sizeof(Res));  
  6.   
  7.     MatchField_t* pmf = pbq->arrMatch[idx];  
  8.   
  9.   
  10.     TCCState *script;  
  11.   
  12.     script = tcc_new();  
  13.     if (!script)   
  14.     {  
  15.         writelog(LOG_ERROR, "Could not create tcc state\n");  
  16.         return;  
  17.     }  
  18.   
  19.     tcc_set_output_type(script, TCC_OUTPUT_MEMORY);  
  20.   
  21.     //编译脚本文件   
  22.     if (tcc_add_file(script, "./script/hit.c") == -1)  
  23.     {  
  24.     writelog (LOG_ERROR, "Compiling error");  
  25.     tcc_delete(script);  
  26.     return;  
  27.     }  
  28.   
  29.     //添加内部符号给脚本使用   
  30.     //tcc_add_symbol(s, "add", add);   
  31.   
  32.     // relocate the code   
  33.     if (tcc_relocate(script, TCC_RELOCATE_AUTO) < 0)  
  34.     {  
  35.     tcc_delete(script);  
  36.     return;  
  37.     }  
  38.       
  39.     //定义函数指针   
  40.     int (*func)(MatchField_t*, MatchResult_t*, char*, int);  
  41.   
  42.     //获取函数地址   
  43.     func = tcc_get_symbol(script, "hitMatch");  
  44.     if (!func)  
  45.     {  
  46.     tcc_delete(script);  
  47.     return;  
  48.     }  
  49.   
  50.     //通过函数地址 调用函数   
  51.     int ret = func(pmf, &Res, vbuf, vsiz);  
  52.     if(ret == 0)  
  53.     {  
  54.         //TODO...   
  55.     }  
  56.     tcc_delete(script);  

脚本 hit.c 代码如下 :

  1. int hitMatch (MatchField_t* pmf, MatchResult_t* pcr, char* vbuf, int vsiz)  
  2. {  
  3.     memcpy (pcr->dataType, vbuf, sizeof(int));  
  4.     //TODO....   
  5.     return 0;  
  6. }  
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Tiny C Compiler 嵌入式使用帮助
使用tcc编译器
斐波拉契数列(go)
一步一步学习Swift之(四)玩转UIWebView
C1
递归和迭代
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服