2010-08-23 132 views
9

在一些LLVM教程,我看到它是相当容易的C函数绑定到基于LLVM的自定义语言。 LLVM向程序员传递一个指向该函数的指针,该函数可以与LLVM生成的代码混合在一起。LLVM自动C++链接

什么是与C++库做到这一点的最好方法。假设我有一个相当复杂的库,比如Qt或Boost,我想绑定到我的自定义语言。我是否需要创建存根库(如Python或Lua需求),还是LLVM提供某种外部函数接口(FFI)?

回答

12

在我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)和一个指向C字符串数据的初始化。

+0

获取提供简洁代码示例的答案。谢谢!正是我所期待的。 – 2010-08-24 12:47:21

3

如果你编译C++和一些其他语言LLVM位码一些代码,它应该是完全有可能将这些理论联系在一起,让一个呼叫中的其他...。在实际中,您需要粘合代码来在不同语言的类型之间进行转换(例如,除非使用CPython,否则在C++中没有与Python字符串等效的内容,因此void reverse(std::string s)需要使用str进行调用,更糟的是,整个对象模型是非常不同的)。 Qt具有很多魔术,编译后可能需要更多努力才能暴露出来。此外,我可能还有其他潜在的问题,我不知道。

即使这样的作品,这是潜在的非常丑陋使用。尽管Python非常方便的描述符,但PyQt仍然有get*set*的功能 - 并且PyQt付出了很多努力,他们不仅创建了一些存根。