2010-08-23 5 views
9

In alcune delle esercitazioni LLVM mi sono reso conto che è abbastanza facile associare la funzione C in un linguaggio personalizzato basato su LLVM. LLVM fornisce al programmatore un puntatore alla funzione che può essere quindi combinata con il codice generato da LLVM.LLVM collegamento automatico C++

Qual è il metodo migliore per farlo con le librerie C++. Diciamo che ho una libreria abbastanza complessa come Qt o Boost che voglio associare al mio linguaggio personalizzato. Devo creare una libreria stub (come richiedono Python o Lua) o LLVM offre una sorta di interfaccia di funzione straniera (FFI)?

risposta

12

Nel mio codice LLVM, creo le funzioni di wrapper extern "C" per questo e inserisco dichiarazioni di funzione LLVM nel modulo per chiamarle. Quindi, un buon modo per far conoscere a LLVM le funzioni non è di lasciarlo usare dlopen e cercare il nome della funzione nel file eseguibile (questo è un rompicapo, dato che i nomi delle funzioni devono essere nella sezione .dynsym, ed è anche lento), ma per fare la mappatura manualmente, usando ExecutionEngine::addGlobalMapping.

solo ottenere il llvm::Function* di tale dichiarazione e l'indirizzo della funzione come indicato in C++ da &functionname convertito in void* e passare queste due cose insieme a LLVM. Il JIT che esegue le tue cose saprà quindi dove trovare la funzione.

Ad esempio, se si vuole avvolgere QString è possibile creare diverse funzioni che creano, distruggono e le funzioni di un tale oggetto

extern "C" void createQString(void *p, char const*v) { 
    new (p) QString(v); // placement-new 
} 

extern "C" int32_t countQString(void *p) { 
    QString *q = static_cast<QString*>(p); 
    return q->count(); 
} 

extern "C" void destroyQString(void *p) { 
    QString *q = static_cast<QString*>(p); 
    q->~QString(); 
} 

creare e richiamare le dichiarazioni adeguati e una mappatura. Quindi è possibile call queste funzioni, passando lungo un'area di memoria adeguatamente allineata e dimensionata per QString (possibilmente alloca 'ed) e un i8* che punta ai dati di stringa C per l'inizializzazione.

+0

Ottiene la risposta per fornire esempi concisi di codice. Grazie! esattamente quello che stavo cercando. –

3

Se si compila del codice in C++ e alcuni in un altro linguaggio in codice LLVM, dovrebbe essere perfettamente possibile collegarli tra loro e lasciare che uno chiami l'altro ... in teoria. In pratica, avrete bisogno del codice colla per convertire tra i diversi tipi di lingua (ad es. Non c'è equivalente a una stringa Python in C++ a meno che non si usi CPython, quindi perè possibile chiamarlo con uno str è necessaria una conversione - peggio, l'intero modello oggetto è molto diverso). E Qt in particolare ha un sacco di magia che potrebbe richiedere molto più sforzo per esporre dopo le compilation. Inoltre, potrebbero esserci ulteriori potenziali problemi di cui non sono a conoscenza.

E anche se funziona, è potenzialmente molto brutto da usare. Ci sono ancora le funzioni get* e set* in tutto PyQt nonostante i descrittori molto convenienti di Python - e con molto sforzo in PyQt, non hanno creato solo alcuni stub.