我想使用clang / llvm API编译以字符串定义的c函数,并立即执行它。类似于:
void main() {
std::string codestr = "int foo(int bar) { return bar * 2; }"
clang::??? *code = clang::???.compile(codestr);
int result = code->call("foo", 5);
}
我正在寻找教程,但是到目前为止我发现的内容与我的目标不完全匹配或不起作用,因为它是指LLVM的过时版本。当前,我正在使用LLVM 3.5。
有人在手边有很好的教程吗?
我跟随this blog post获得了不错的结果。 clang API已更改,因此您可能需要进行调整。使用LLVM 3.6.1,使用以下代码可获得不错的效果:
llvm::Module* compile(const char* filename) {
clang::CompilerInstance compiler;
clang::CompilerInvocation* invocation = new clang::CompilerInvocation();
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());
auto diagOptions = new clang::DiagnosticOptions();
clang::DiagnosticsEngine Diags(DiagID, diagOptions,
new clang::TextDiagnosticPrinter(llvm::errs(), diagOptions));
std::vector<const char *> arguments = {filename};
clang::CompilerInvocation::CreateFromArgs(*invocation,
&*arguments.begin(), &*arguments.end(),
Diags);
compiler.setInvocation(invocation);
compiler.setDiagnostics(new clang::DiagnosticsEngine(DiagID, diagOptions,
new clang::TextDiagnosticPrinter(llvm::errs(), diagOptions)));
std::unique_ptr<clang::CodeGenAction> action(new clang::EmitLLVMOnlyAction());
compiler.ExecuteAction(*action);
std::unique_ptr<llvm::Module> result = action->takeModule();
llvm::errs() << *result;
return result.release();
}
我对指针非常粗心,因此很可能发生内存泄漏或双倍的空闲(尽管它没有崩溃)。
我不知道如何从内存缓冲区中获取源,因此我使用mkstemp
将其转储到了临时文件中。