我正在编写一个LLVM脚本引擎,JIT使用自定义语言编写脚本代码。我的问题是我无法调用外部函数(即使C99 erf()函数失败)。
例如,如果我extern“C”erf函数,
extern "C" double erft(double x){
return erf(x);
}
并创建一个具有外部链接的函数
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);
使用erft(0.0)运行我的脚本时收到以下错误消息:
LLVM错误:程序使用的外部函数'erft'无法解决!
手动执行映射,
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
会出现以下错误:
声明`void llvm :: ExecutionEngine :: addGlobalMapping(const llvm :: GlobalValue *,void *)'在类之外不是定义
显然我做错了。任何帮助将不胜感激
答案 0 :(得分:15)
假设您尚未禁用它(通过调用EE->DisableSymbolSearching()
),则LLVM将使用dlsym()
在JIT程序本身中查找符号。根据您的平台,这可能意味着您需要使用-fPIC
构建JIT,或者根本不可用(例如在Windows上)。
除了自动符号搜索之外,您始终可以使用EE->addGlobalMapping(GV, &function)
自己注册各个函数,其中GV =与您正在调用的本机函数匹配的llvm :: Function *函数声明。在你的情况下使用ertf():
EE->addGlobalMapping(erft, &::erft);
请注意,您将全局函数erft()
和局部变量erft
命名为“::”。请在下次选择不同的名字!
答案 1 :(得分:2)
可能会发生这种情况,因为您忘记添加“libm”依赖项,请尝试使用:
[your module]->addLibrary("m");
有关Module::addLibrary()
。
答案 2 :(得分:0)
我不知道llvm,但这没有意义:
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
它在C ++中定义了一个新函数。你需要做的是以某种方式用LLVM注册你的功能。定义该函数就像尝试向LLVM类添加新方法,而不是您想要做的事情。