假设我在执行期间生成了一个C程序:
source = "int add_x_y(int x, int y){ return x + y; }"; source_size = 42;
我想要以下function:
void* compile(char* source, int source_size);
这样:
int (*f)(int,int) = compile(source, source_size); printf("%dn",f(2,3));
输出:
5
compile
不能依赖于外部工具(编译器),因为我想在emscripten(将C程序转换为.js文件)中使用它。
那可能吗?
其他人可能比我更好地填写一些细节,但如果你不介意呼唤GCC或链接到它,它应该是可行的。 如果将代码写入文件,则将文件编译为共享库(.SO)。 从那里,加载共享库并获取所需符号的地址是一件简单的事情。
它是操作系统和处理器特定的。 我想你是在Linux x86-64(64位x86)或ia32(32位x86)
你可以使用tinycc (它是一个编译器,可以快速编译C代码到非常慢和libtcc
优化的机器代码),它提供了一个包含tcc_compile_string
函数的库libtcc
。
您可以使用JIT编译库,如libjit , GNU lightning , asmjit , LLVM (以及GCC 5将具有JIT-ingfunction )。
你只需将你的字符串写入一些临时的C文件/tmp/genfoo.c
(如果该文件位于tmpfs
文件系统中,不涉及真正的磁盘IO,那么它很快)然后分叉一个真正的命令:
gcc -Wall -fPIC -shared -O /tmp/genfoo.c -o /tmp/genfoo.so
然后dlopen(3)生成的/tmp/genfoo.so
共享对象(和dlsym
从其名称中获取一个函数指针)。
如果您想要生成生成的代码,您需要一个真正的优化编译器,如GCC或Clang / LLVM ; 编写临时源文件(并在编译器中解析)的开销可以忽略不计:大部分工作都在优化过程中的编译器内部。 生成C代码是实用的,特别是当您希望生成的代码由某些C编译器进行优化时 。
请注意,所有这些技术可能无法在emscripten中运行 ,因为您可能无法将数据指针强制转换为函数指针(从法律上讲 , 强制转换可能是C99中未指定的行为,但我上面提到的所有方法都需要它,而你在你的问题中做这样的演员)! 如果您需要在浏览器中生成代码,则可能需要生成一些Javascript或其子集(例如,对于asm.js )。 请参阅在Emscripten中从C / C ++调用Javascript
如果您正在开发一种在浏览器中运行的语言,请使该语言生成一些Javascript(例如asm.js
)。
另请参阅NaCl (Google浏览器上的Native Client)
以上就是c/c++开发分享如何在执行期间编译C代码,并获得指向相应函数的指针?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/562186.html