LLVM автоматическое связывание C ++ - PullRequest
9 голосов
/ 24 августа 2010

В некоторых руководствах по LLVM я видел, как довольно легко связать функцию C с пользовательским языком, основанным на LLVM.LLVM передает программисту указатель на функцию, которая затем может быть смешана с кодом, генерируемым LLVM.

Какой лучший способ сделать это с библиотеками C ++.Допустим, у меня есть довольно сложная библиотека, такая как Qt или Boost, которую я хочу привязать к своему пользовательскому языку.Нужно ли создавать библиотеку-заглушку (как требуют Python или Lua) или LLVM предлагает какой-то интерфейс сторонних функций (FFI)?

Ответы [ 2 ]

13 голосов
/ 24 августа 2010

В своем коде LLVM я создаю для этого extern "C" функции-оболочки и вставляю объявления функций LLVM в модуль для их вызова. Тогда, хороший способ сообщить LLVM о функциях - это не позволить ему использовать dlopen и искать имя функции в исполняемом двоичном файле (это задница в заднице, поскольку имена функций должны быть в .dynsym, и это тоже медленно), но сделать сопоставление вручную, используя ExecutionEngine :: addGlobalMapping .

Просто получите llvm::Function* этого объявления и адрес функции, заданный в C ++ как &functionname, преобразованный в void*, и передайте эти две вещи LLVM. JIT, выполняющий ваши вещи, будет знать, где найти функцию.

Например, если вы хотите обернуть QString, вы можете создать несколько функций, которые создают, уничтожают и вызывают функции такого объекта

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();
}

И создать правильные объявления и сопоставление. Затем вы можете call эти функции, передавая область памяти, соответствующим образом выровненную и измеренную для QString (возможно, alloca 'ed) и i8*, указывающих на данные строки C для инициализации.

3 голосов
/ 24 августа 2010

Если вы компилируете некоторый код на C ++, а другой на другом языке - в битовый код LLVM, то должно быть совершенно возможно связать их вместе и позволить одному вызывать другой ... теоретически.

На практике вам понадобится склеенный код для преобразования между типами разных языков (например, нет эквивалента строки Python в C ++, если вы не используете CPython, поэтому для void reverse(std::string s) можно вызывать с str, вам нужно преобразование - хуже, вся объектная модель сильно отличается). И, в частности, в Qt много магии, которая может потребовать гораздо больше усилий для раскрытия после компиляции. Кроме того, могут быть и другие потенциальные проблемы, о которых я не знаю.

И даже если это сработает, потенциально очень уродливо использовать. В PyQt все еще есть функции get* и set*, несмотря на очень удобные дескрипторы Python - и много усилий было уделено PyQt, они не просто создали некоторые заглушки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...