BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース CXXが実現するRustとC++の安全な相互運用

CXXが実現するRustとC++の安全な相互運用

ブックマーク

原文(投稿日:2020/12/06)へのリンク

CXXは安全な低レベルバインディング経由でC++コードとRustコードの相互呼び出しを可能にするソフトウェアだ。安全ではないC言語形式のシグネチャ上に外部関数インターフェースを構築する必要はない。InfoQは今回、作者のDavid Tolnay氏と話す機会を持つことができた。

CXXは型と関数シグネチャの静的解析を使用して、RustとC++双方の不変性を担保する。その上で一対のコードジェネレータを使用して、両サイドのバウンダリを効率的に実装する同時に、以降のビルドプロセスにおいて正確性を検証するために必要な静的アサーションを生成する。

Tolnay氏によると、CXXを使用して生成したブリッジでは、コピーやシリアライゼーション、メモリアロケーション、ランタイムチェックが必要ないため、そのオーバーヘッドはゼロないし無視できる範囲である。

CXXはブリッジの両側において、ごく普通のコードを記述できることを目標にしている。すなわち、自然なC++コードを使って自然なRustコードを記述することや、その逆が可能になるのだ。このためにCXXでは、stringやvectorなど、標準ライブラリの型に対するバインディングを組み込みで提供している。

CXXを使用したRustプログラムからのC++コードの呼び出しは次のように行う。

#[cxx::bridge]
mod ffi {
    unsafe extern "C++" {
        include!("cxx-demo/include/blobstore.h");

        type BlobstoreClient;

        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
    }
}

fn main() {
    let client = ffi::new_blobstore_client();
}

作者のDavid Tolnay氏に話を聞いた。

InfoQ: ご自身のバックグラウンドと、Rustプロジェクトとの関わりについて説明してください。

Tolnay: サンフランシスコ地域に住むソフトウェアエンジニアで、ライブラリやパターン、大規模コードベース(1,000万ライン以上)を扱うためのプラクティスなど、主としてコードベースの設計に関わっています。2016年からRustを使って、広範に使用されているライブラリをサイドプロジェクトとして数多く開発し、メンテナンスしています。今ではRustパッケージレジストリにあるすべてのオープンソースパッケージの30パーセント近くが、私の開発したライブラリを、少なくともひとつは直接的に利用しています。

InfoQ: CXXを開発した理由について教えてください。これを作ろうと思った動機は何でしたか?

Tolnay: CXX以前でも、RustのC言語との相互運用性に問題はなかった(安全ではないが、C開発者にとっては慣れた方法)のですが、C++との相互運用性に関しては、"管理可能なように、できる限りC言語のように記述する"必要がありました。

状況としては、Rustに詳しいチームが主体となって、必要な部分でC++コードを呼び出して職務を遂行する、というようなものだったのです。しかしこれでは当然、記述も維持も困難ですし、

Rustを始めたばかりのチームは大変な苦労をすることになります。RustをC++コードベースに導入した人、特にRustとC++のいずれの経験もなくRustに来た人にとっては、開始早々から安全でないコードの山を見るのは興醒めですし、Rustに対して否定的になるきっかけにもなります。

CXXは、Rustと最近のC++の間にはC言語よりも共通部分が多い、という点を活用しています。安全でないC言語を挟まなくても、適切な抽象化レベルにおいて、言語バウンダリ上で効率を犠牲にすることなく、相互運用が可能なのです。

InfoQ: CXXを設計し実装する中で、最も大きな課題は何でしたか、あるいは何でしょうか?

Tolnay: Cargoユーザに適切なエクスペリエンスを提供することです。Cargoは、オープンソースのRustプロジェクトでは一般的に使用されているビルドシステムです。Bazelなど一部のビルドシステムでは、複数言語ビルドを対象とした高度な設計が行われていますが、Cargoはそうではありません。

根本的な再設計も数回ありましたが、Cargo上のCXXは、ネイティブな多言語ビルドシステムでのCXXエクスペリエンスとほぼ一致するところまで来ています。そのエクスペリエンスの中には、C++に依存するRust、Rustに依存するC++、他クレートのC++に依存するC++が含まれています。

InfoQ: CXXの現在の状態はどのように説明できるのでしょう?現時点で推奨できるシナリオは、どのようなものでしょうか?

Tolnay: Rust/C++ハイブリッドの大規模なコードベースにCXXをロールアウトしていますが、多くのエンジニアによって使用されて、好評を博しています。改善の余地はありますが、すべてのRust-C++相互運用機能に対する推奨事項として、私が支持する開発者エクスペリエンスを提供しています。

InfoQ: ロードマップはどのようになっていますか?

Tolnay: 未検討のアイデアとして最大のものは、非同期関数のファーストクラスサポートです。非同期処理はすでにサポートしていますが、任意のC++関数を.awaitしたり、任意のRust関数をco_awaitしたりできるほどシームレスではありません。

CXXを試してみたいならば、まずはチュートリアルGitHubリポジトリから始めるとよいだろう。

この記事に星をつける

おすすめ度
スタイル

BT