Tiny C Compiler/TCC调用方法与使用说明

来源:互联网 发布:raid0数据恢复 编辑:程序博客网 时间:2024/05/16 23:43

    最近用到了开源C编译器TCC,在网上查了些资料,关于调用方法等内容不是十分完整,因此在实践的基础上作了总结,整理了学习笔记。

 

一、编译TCC源代码(版本tcc-0.9.25

1、 安装MinGWMSYS

TCC提供的源代码没有VC的工程文件,只有MinGW.c文件,因此可以使用MinGW进行编译。

安装方法:

http://prdownloads.sourceforge.net/mingw下载MinGW-5.1.6.exe,这只是一个用于安装的程序,并不是编译器程序。运行该程序后,它会自动下载压缩文件进行安装。如果不想直接从外网安装,可分别下载压缩文件,放在内网服务器上。MinGW-5.1.6.exe运行后,会生成一个配置文件mingw.ini,可以对其进行修改,替换掉自动生成的配置文件,直接从内网安装。

也可以手动安装,步骤较为麻烦,不作详细描述。

2、 编译源代码生成dll

运行MinGW,编译源代码,生成libtcc.dll,命令为

gcc -O2 -shared -Wall -Wl,--export-all-symbols -mpreferred-stack-boundary=2 -march=i386 -falign-functions=0 -fno-strict-aliasing -DTCC_TARGET_PE -DLIBTCC -o libtcc.dll tcc.c

3、 生成.def文件

下载pexports.exe并运行,生成def文件,命令为

Pexports libtcc.dll > libtcc.def

如不指定路径,def文件直接生成在pexports.exe所在文件夹下。

4、 生成.lib文件

使用VS2008命令行(在Visual Studio Tools中),生成lib文件,命令为

Lib /machine:i386 /def:libtcc.def

可先转至libtcc.def所在文件夹下再执行命令。

 

如果使用VS来编译,应将工程编码设置为ANSII,不能使用Unicode

二、              DLL形式的调用方法

1、 libtcc.dlllibtcc.lib拷至已建立的工程的文件夹下(还包括libinclude文件夹及tcc.h等文件)。

2、 在主程序代码中引用tcc.hlib文件,代码为

#include “D://tcc//tcc.h”  //tcc.h文件的绝对路径

#pragma comment (lib,”D://tcc//libtcc.lib”)  //lib文件的绝对路径

3、 测试代码如下(参考源代码中提供的示例代码):

#include <stdio.h>

#include "D://tcc// tcc.h"

#pragma comment(lib, "D://tcc//Libtcc.lib")

 

int add(int a, int b)

{

return a + b;

}

 

char my_program[] =

"int fib(int n)/n"

"{/n"

"    if (n <= 2)/n"

"        return 1;/n"

"    else/n"

"        return fib(n-1) + fib(n-2);/n"

"}/n"

"/n"

"int foo(int n)/n"

"{/n"

"    printf(/"Hello World!//n/");/n"

"    printf(/"fib(%d) = %d//n/", n, fib(n));/n"

"    printf(/"add(%d, %d) = %d//n/", n, 2 * n, add(n, 2 * n));/n"

"    return 0;/n"

"}/n";

 

int main(int argc, char *argv[])

{

TCCState *s = tcc_new();

tcc_set_lib_path(s, "D://tcc");

tcc_set_output_type(s, TCC_OUTPUT_MEMORY);   //设置内存输出模式

 

if (tcc_compile_string(s, my_program) == -1)

{

   printf("compile error/n");

   return 1;

}

 

tcc_add_symbol(s, "add", add);

int size = tcc_relocate(s, NULL);

 

if (size == -1)

 return 1;

 

void *mem = malloc(size);

tcc_relocate(s, mem);

void (*func)(int);

func = (void(*)(int))tcc_get_symbol(s, "foo");

if (!func) return 1;

func(32);

tcc_delete(s);

free(mem);

 

return 0;

}

如果测试程序出现undefined symbol: printf这样的错误提示,注意工程的编码格式是否为Unicode,应该为ANSII。函数的调用顺序基本遵照范例程序中的顺序。

 

三、              直接调用及TCC命令说明

 

Tcc.exe本身没有界面,通过cmd来运行,主程序可以直接进行调用。方法如图一

程序需添加using System.IO(使用stream)和using System.Diagnostics(使用process

参数的格式必须正确,不要遗漏空格。需要加上psiTcc.RedirectStandardError = true,否则无法获得错误信息。

 

三、              如何通过TCC编译调用外部DLLC代码

1、 使用tiny_impdef.exe为要调用的动态库生成def文件。命令为

Tiny_impdef xxxx.dll –o xxxx.def

VS中通过lib文件调用dll,需要添加#pragma comment(lib,”xxxx.lib”)tcc中使用def而不是lib,因此不需要添加该语句。

2、 需要将xxxx.dll放在tcc.exe所在的文件夹下(或者能够通过环境变量找到)。

3、 代码中声明所有用到的函数。

4、 调用tcc编译代码,命令为

C:/tcc/tcc.exe program.c -I"C:/tcc/include" -L"C:/tcc/lib" -lxxxx -o program.exe

其中,program.c是调用dll的程序代码;-I指定所引用的头文件的路径,默认路径是C:/tcc/include-L指定def所在文件夹的路径,默认为C:/tcc/lib-ldef文件的名称,如引用的defxxxx.def,则命令格式为-lxxxx-o指定生成的文件,也可使用-run,即不生成exe而直接从内存运行。需要引用多个dll时,如xxx1.defxxx2.def,命令为-lxxx1 –lxxx2

5、 代码示例:(图二)