9

いくつかのLLVMチュートリアルでは、C関数をLLVMに基づくカスタム言語にバインドするのがかなり簡単であることがわかりました。LLVMは、LLVMによって生成されているコードと混合できる関数へのポインターをプログラマーに渡します。

C++ライブラリでこれを行うための最良の方法は何ですか。QtやBoostのようなかなり複雑なライブラリがあり、カスタム言語にバインドしたいとします。スタブライブラリ(PythonやLuaが必要とするような)を作成する必要がありますか、それともLLVMはある種の外部関数インターフェイス(FFI)を提供しますか?

4

2 に答える 2

13

私のLLVMコードでは、extern "C"このためのラッパー関数を作成し、それらを呼び出すためにLLVM関数宣言をモジュールに挿入します。次に、LLVMに関数について知らせる良い方法は、実行中のバイナリで関数名を使用および検索しないことです(関数名はセクションにdlopen含める必要があるため、これはお尻の痛みです。.dynsymも遅いです)が、ExecutionEngine::addGlobalMappingを使用して手動でマッピングを行うには。

llvm::Function*その宣言とC++で指定された関数のアドレスを&functionname変換して取得し、void*これら2つを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();
}

そして、適切な宣言とマッピングを作成します。次に、これらの関数を実行して、適切に配置およびサイズ設定された(場合によっては'ed)callメモリ領域を渡し、初期化のためにC文字列データをポイントします。QStringallocai8*

于 2010-08-23T21:31:03.410 に答える
3

一部のコードをC++でコンパイルし、一部を別の言語でLLVMビットコードにコンパイルする場合、これらをリンクして、理論上、一方を他方に呼び出すことは完全に可能です。

実際には、異なる言語のタイプ間で変換するためのグルーコードが必要になります(たとえば、CPythonを使用しない限り、C ++にはPython文字列に相当するものがないためvoid reverse(std::string s)str変換が必要です-さらに悪いことに、オブジェクトモデル全体非常に異なります)。また、Qtには特に多くの魔法があり、コンパイル後に公開するにはさらに多くの労力が必要になる場合があります。また、私が気付いていないさらなる潜在的な問題があるかもしれません。

そしてそれがうまくいったとしても、それを使うのは潜在的に非常に醜いです。Pythonの非常に便利な記述子にもかかわらず、PyQt全体にまだ機能があります。get*そして、 PyQtに多大な労力が費やされ、スタブを作成するだけではありませんでした。set*

于 2010-08-23T21:30:42.100 に答える