【问题标题】:LLVM automatic C++ linkingLLVM 自动 C++ 链接
【发布时间】:2010-08-23 21:11:21
【问题描述】:

在一些 LLVM 教程中,我看到将 C 函数绑定到基于 LLVM 的自定义语言相当容易。 LLVM 给程序员一个指向函数的指针,然后可以将其与 LLVM 生成的代码混合在一起。

使用 C++ 库执行此操作的最佳方法是什么。假设我有一个相当复杂的库,如 Qt 或 Boost,我想绑定到我的自定义语言。我需要创建存根库(如 Python 或 Lua 需要),还是 LLVM 提供某种外部函数接口 (FFI)?

【问题讨论】:

    标签: c++ llvm


    【解决方案1】:

    在我的 LLVM 代码中,我为此创建了 extern "C" 包装函数,并将 LLVM 函数声明插入到模块中以便调用它们。然后,让 LLVM 了解函数的一个好方法是不要让它使用 dlopen 并在执行的二进制文件中搜索函数名(这很麻烦,因为函数名需要在 @ 987654324@ 部分,也很慢),但要手动进行映射,使用ExecutionEngine::addGlobalMapping

    只需获取该声明的llvm::Function*&functionname 在C++ 中给出的函数地址,转换为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 字符串数据进行初始化的适当对齐和大小的内存区域。

    【讨论】:

    • 获得提供简洁代码示例的答案。谢谢!正是我想要的。
    【解决方案2】:

    如果您将一些 C++ 代码和一些另一种语言的代码编译为 LLVM 位码,则完全有可能将它们链接在一起并让一个调用另一个......理论上。

    实际上,您将需要胶水代码在不同语言的类型之间进行转换(例如,除非您使用 CPython,否则 C++ 中没有与 Python 字符串等效的字符串,因此您需要使用 str 调用 void reverse(std::string s)转换 - 更糟糕的是,整个对象模型非常不同)。 Qt 特别有很多魔力,在编译后可能需要更多的努力才能暴露出来。此外,可能还有其他我不知道的潜在问题。

    即使这样可行,使用起来也可能非常难看。尽管 Python 有非常方便的描述符,但 PyQt 中仍然有 get*set* 函数 - PyQt 付出了很多努力,它们不只是创建一些存根。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-12
      • 1970-01-01
      相关资源
      最近更新 更多