コンテンツへスキップ
ものがたり
戻る

CXXIがクロスプラットフォームでC++/C# interopを実現する(予定)

monoチームからCXXIという新しいコンポーネントが登場しました。これはC++とC#のinteroperabilityを実現するフレームワークだそうです。

》 CXXI: Briding the C++ and C# worlds. http://tirania.org/blog/archive/2011/Dec-19.html

以前からcppinteropという名前で作っていたハカーたちがいて、7月のMonospace conferenceでも発表されていたのですが、それがブラッシュアップされて登場したのがコレです。

》 mono / cxxi https://github.com/mono/cxxi

以下、6割方↑記事の内容を引っ張ってきています。

CXXIの機能・特徴

CXXIが実際にサポートする機能は、ざっと次のようなものだそうです(便宜上C#と.NETはまとめてC#と書きます):

通常のP/InvokeやMarshalByRefObjectよりは、C++を実用的に使えるものと言えるでしょう。他のC++ interopはどうなっていたんでしょうか?

CXXIランタイム

ではCXXIはどのように実装されているのかというと、バイナリレベルでC++のオブジェクトの内容を読み取って、それをもとにC#ベースのクラス構造やメソッド呼び出しを実現します。その具体的な仕組みを知るために、まずC++でコンパイルされたネイティブコードがどのようなバイナリ構造をもっているかを知る必要があるでしょう:

これらがどのようにコード上で展開されるかは上記リンク先に例があります。

CXXIでは、引数やオブジェクト自体のメモリレイアウトを操作するために、プラットフォーム依存のオブジェクトレイアウトを知る必要があり、また非仮想メソッドを呼び出すためにmangled nameを把握しておく必要があります。

以上でも随所で説明しましたが、CXXIは、その仕組み上、プラットフォーム/アーキテクチャとコンパイラに依存します。

CXXIでは、対象ライブラリのC++ヘッダを入力として、CXXIランタイム(Mono.Cxxi.dll)を経由してC++オブジェクトを操作するC#クラスのソースを生成します。

how cxxi uses C++ headers and libs

CXXIランタイムの実際の動作は次のような感じになります:

CXXIジェネレータの仕組み

次はCXXIでC++ヘッダからC#ソースを生成するジェネレータについて。CXXIでは、C++ヘッダからgcc-xml(gcc4の中間コードgimpleのXML表現にコンバートするツール)で生成したXMLを入力として、C#のソースを生成します。生成されるのはソースなので、これに手を加えて最終的なライブラリを生成できます。

how cxxi generator works

ここでポイントとなるのは、生成されたC#コードには、具体的なメモリレイアウトに当てはめられたオブジェクトの情報が含まれているわけではない、つまりまだ環境/アーキテクチャ中立のコードになっている、ということです。具体的なメモリレイアウトの解決は、実行時に行われます。

(ジェネレータではgcc-xmlのみをサポートしていますが、生成されるC#ソースにはgcc依存の部分もMSVC依存の部分も存在せず、またC#ソースの生成に必要なのはヘッダファイルのみなので、gccで解析できるヘッダファイルでさえあれば、困ることは無いはずです。Windowsのヘッダファイルの多くは、cygwinにも含まれるgcc-mingwのw32apiパッケージにも含まれています。)

現状と今後

CXXIは大きな実用の可能性を見せるものですが、未完成の部分もいくつかあります。

というわけで、CXXIのざっとした説明でした。わたしの理解では、cxxiが目指しているのはid:atsushieno:20110628:p1 で書いたBridJやJNAeratorのようなツールなんだろうと思っています。Javaの世界では、この種のC++バインディングツールが百花繚乱というか、それぞれ利点と欠点があって、それぞれが短いライフサイクルで生きているなあという印象がありましたが、C#のバインディングツールとして、CXXIもこれまでのツールとは一線を画した存在として、一石を投じることになりそうです。


この記事を共有:

前の記事
2011年お気に入り作品感謝リスト
次の記事
Mono for Android 4.0がリリースされました