我正在编写一个LLVM脚本引擎,JIT用自定义语言编写脚本代码.我的问题是我无法调用外部函数(即使C99 erf()函数失败).
例如,如果我extern"C"erf函数,
extern "C" double erft(double x){
return erf(x);
}
Run Code Online (Sandbox Code Playgroud)
并创建一个外部链接功能
std::vector<const Type*> Double1(1,Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),Double1,false);
Function *erft = Function::Create(FT,Function::ExternalLinkage,"erft",TheModule);
Run Code Online (Sandbox Code Playgroud)
使用erft(0.0)运行脚本时出现以下错误消息:
LLVM错误:程序使用的外部功能'erft'无法解决!
手动执行映射,
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
Run Code Online (Sandbox Code Playgroud)
会得到以下错误:
在类之外的`void llvm :: ExecutionEngine :: addGlobalMapping(const llvm :: GlobalValue*,void*)'的声明不是定义
显然我做错了.任何帮助将非常感激
小智 15
假设您没有禁用它(通过调用EE->DisableSymbolSearching()),那么LLVM将用于dlsym()在JIT程序本身中查找符号.根据您的平台,这可能意味着您需要构建JIT -fPIC,或者可能根本不可用(例如在Windows上).
除了自动符号搜索之外,您还可以使用EE->addGlobalMapping(GV, &function)GV =与您正在调用的本机函数匹配的llvm :: Function*函数声明来自己注册各个函数.在您的情况下使用ertf():
EE->addGlobalMapping(erft, &::erft);
Run Code Online (Sandbox Code Playgroud)
请注意,您将全局函数erft()和局部变量命名erft为"::".请在下次选择不同的名字!
我不知道 llvm,但这没有意义:
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
Run Code Online (Sandbox Code Playgroud)
这在 C++ 中定义了一个新函数。您需要做的是以某种方式向 LLVM 注册您的函数。定义该函数就像尝试向 LLVM 类添加新方法,而不是您想要做的事情。