2010-12-13 136 views
15

我正在编写一个LLVM脚本引擎,JIT使用自定义语言编译脚本代码。我的问题是我无法调用外部函数(即使C99 erf()函数失败)。将LLVM JIT代码链接到外部C++函数

例如,如果我为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); 

运行我的埃尔夫特河脚本(0.0时收到以下错误消息):

LLVM ERROR: Program used external function 'erft' which could not be resolved!

手动进行映射,

void ExecutionEngine::addGlobalMapping(const GlobalValue * erfF, void * erft); 

会得到我下面的错误:

declaration of `void llvm::ExecutionEngine::addGlobalMapping(const llvm::GlobalValue*, void*)' outside of class is not definition

很显然,我做的事情非常错误的。任何帮助,将不胜感激

+1

未来访问者的警告:答案是引用不推荐的方法。 – antipattern 2017-08-31 08:43:16

+0

[this]的答案(https://stackoverflow.com/questions/48105342/llvm-jit-add-library-to-module)问题显示了如何使用非弃用方法来做到这一点。 – 2018-01-05 15:12:56

回答

0

我不知道LLVM,但这没有任何意义:

void ExecutionEngine::addGlobalMapping(const GlobalValue * erfF, void * erft); 

定义在C新功能++。你需要做的是用LLVM注册你的函数。定义这个函数就像试图向LLVM类添加新的方法,而不是你想要做的。

2

这可能会发生,因为你忘了添加“的libm” depedency,请尝试使用:

[your module]->addLibrary("m"); 

有关Module::addLibrary()更多信息,请参阅here

13

假设您没有禁用它(通过调用EE->DisableSymbolSearching()),LLVM将使用dlsym()来查找JIT程序本身中的符号。根据您的平台,这可能意味着您需要使用-fPIC构建JIT,或者根本不可用(例如在Windows上)。

除了自动符号搜索之外,您始终可以使用EE->addGlobalMapping(GV, &function)自己注册各个函数,其中GV =与您所调用的本地函数相匹配的llvm :: Function *函数声明。在你的情况与ertf()这就是:

EE->addGlobalMapping(erft, &::erft); 

请注意,您指定的全局函数erft()和局部变量erft,因而有“::”。请下次选择不同的名字!