LLVM автоматическое связывание C ++

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

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

9
задан skaffman 23 August 2010 в 21:33
поделиться

2 ответа

В моем 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();
}

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

13
ответ дан 4 December 2019 в 12:57
поделиться

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

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

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

3
ответ дан 4 December 2019 в 12:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: