假设我在执行期间生成了一个C程序:
source = "int add_x_y(int x, int y){ return x + y; }";
source_size = 42;
我想要以下功能:
void* compile(char* source, int source_size);
这样:
int (*f)(int,int) = compile(source, source_size);
printf("%d\n",f(2,3));
输出:
5
并且compile
不能依赖外部工具(编译器),因为我想在emscripten(将C程序转换为.js文件)中使用它。
这可能吗?
答案 0 :(得分:1)
其他人可能比我更好地填写一些细节,但如果你不介意呼唤GCC或链接到它,它应该是可行的。如果将代码写入文件,则将文件编译为共享库(.SO)。从那里开始,只需加载共享库并获取所需符号的地址即可。
答案 1 :(得分:0)
它是特定于操作系统和处理器的。我想你是Linux x86-64(64位x86)或ia32(32位x86)
您可以使用tinycc(它是一个可以快速编译C代码到非常慢和未经优化的机器代码的编译器),它提供了一个包含libtcc
函数的库tcc_compile_string
。
您可以使用JIT-compiling,libjit,GNU lightning,asmjit等LLVM库(GCC 5将有JIT-ing abilities)。
你只需将你的字符串写入一些临时C文件/tmp/genfoo.c
(如果该文件位于tmpfs
文件系统中,则不涉及真正的磁盘IO,因此速度很快)然后分叉真正的命令:
gcc -Wall -fPIC -shared -O /tmp/genfoo.c -o /tmp/genfoo.so
然后dlopen(3)生成的/tmp/genfoo.so
共享对象(和dlsym
从其名称中获取函数指针)。
如果您想要生成生成的代码,则需要真实的optimizing compiler GCC或Clang/LLVM;编写临时源文件(并在编译器中解析)的开销可以忽略不计:大部分工作都在优化过程中的编译器内部。 Generating C code是实用的,特别是当您希望某些C编译器对生成的代码进行优化时。
请注意,所有这些技术可能都不会在emscripten内工作,原因很简单,因为您可能无法将数据指针强制转换为函数指针(从法律上讲,强制转换可能是C99中未指定的行为,但所有我上面提到的方法需要它,你在你的问题中做这样的演员)!如果您需要在浏览器中生成代码 ,则可能需要生成一些Javascript或其子集(例如asm.js)。见calling Javascript from C/C++ in Emscripten
如果您正在开发要在浏览器中运行的语言,请使该语言生成一些Javascript(例如asm.js
)。
另请参阅NaCl(Google浏览器上的Native Client)