2010-12-13 133 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,因而有「::」。請下次選擇不同的名字!