Dans mon code LLVM, je crée des fonctions wrapper extern "C"
pour cela, et j'insère des déclarations de fonctions LLVM dans le module pour les appeler. Ensuite, un bon moyen de faire connaître LLVM sur les fonctions est de ne pas le laisser utiliser dlopen
et de chercher le nom de la fonction dans le binaire en cours d'exécution (cela est pénible car les noms des fonctions doivent être dans la section .dynsym
, et il est trop lent), mais pour faire le mappage manuellement, en utilisant ExecutionEngine::addGlobalMapping.
Procurez-vous le llvm::Function*
de cette déclaration et l'adresse de la fonction donnée en C++ par &functionname
converti en void*
et passer ces deux choses le long de LLVM. Le JIT exécutant vos trucs saura alors où trouver la fonction.
Par exemple, si vous vouliez envelopper QString
vous pouvez créer plusieurs fonctions qui créent, détruisent et appellent des fonctions d'un tel objet
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();
}
et de créer des déclarations appropriées et une cartographie. Ensuite, vous pouvez call
ces fonctions, en passant le long d'une région de mémoire convenablement alignés et dimensionnés pour QString
(éventuellement alloca
'ed) et un i8*
pointant vers les données de chaîne C pour l'initialisation.
Obtient la réponse pour fournir des exemples de code concis. Merci! exactement ce que je cherchais. –