C#からC++ のコードトランスレータの設計と開発は、CodePortingによって単独で行われました。これには多くの調査、複数のアプローチの適用、およびメモリモデルなどの異なるテストが必要でした。最終的に、2つのソリューションが選択されました。そのうちの1つは、現在Aspose製品のC++リリースで使用されています。
次に、コードトランスレータで使用している技術について説明します。トランスレータはC#で書かれたコンソールアプリケーションであり、これによりtranslate-compile-testなどの一般的なシーケンスを実行するスクリプトに埋め込むことが容易です。また、同じ操作をボタンをクリックすることで実行できるGUIコンポーネントもあります。
構文解析は、古いトランスレータの世代ではNRefactoryライブラリによって、新しいトランスレータではRoslynによって実行されています。
トランスレータは、情報を収集し出力C++ コードを生成するためにいくつかのAST treeのウォークスルーを使用しています。C++ コードにはAST表現が作成されていないため、代わりに純粋なテキスト形式で出力コードを処理しています。
トランスレータを微調整するために追加の情報が必要な場合があります。この情報はオプションと属性を介して渡されます。オプションはプロジェクト全体に適用されます。通常、クラスのエクスポートマクロ名を指定するためや、コードの解析時に使用されるC#の条件付きシンボルを指定するために使用されます。属性は型やエンティティに適用され、それらに特定の情報を提供します。たとえば、どのクラスメンバーが翻訳されたコードでconst
またはmutable
修飾子を必要とするか、どのエンティティを翻訳から除外するかを示します。
C#のクラスと構造はC++ のクラスに変換されます。メンバーとソースコードは最も近いアナログに変換されます。ジェネリックな型とメソッドはC++ のテンプレートにマップされます。C#の参照はスマートポインタ(共有または弱い)に変換されます。参照クラスはライブラリで定義されています。コードトランスレータの他の内部詳細については、別の記事で説明します。
だから、C#からC++へのプロジェクトの翻訳は、.NETライブラリの代わりに私たちのライブラリに依存しています:
Cmakeを使用して、コードトランスレータライブラリと翻訳されたプロジェクトをビルドしています。現在、VS 2017および2019(Windows)、GCC、およびClang(Linux)コンパイラをサポートしています。
既に述べたように、私たちの.NET実装のほとんどは、以下のサードパーティライブラリの薄いアダプターです:
トランスレータとライブラリの両方には多くのテストがあります。ライブラリのテストはGoogleTestフレームワークを使用しています。トランスレータのテストは主にNUnit/xUnitで書かれており、次のことを確認しています:
バージョン管理システムとしてGitLabを使用しており、CIにはJenkinsを利用しています。翻訳された製品はNuGetパッケージとダウンロード可能なアーカイブとして提供されています。
このプロジェクトを進行する中で、さまざまな問題に直面しました。その中には予想されたものもあれば、途中で明らかになったものもあります:
Object
型の代替がなく、ほとんどのライブラリクラスにRTTIがありません。これにより、.NETの型をSTLの型にマッピングすることは不可能です。yield
)。それでも、コードトランスレータプロジェクトは技術的な観点から非常に興味深く、学術的な複雑さは私たちに常に新しいことを学ばせてくれます。
コードトランスレータプロジェクトに取り組んでいる間に、コード翻訳の興味深い学術的課題を解決するシステムを実装することに成功しました。Asposeライブラリの月次リリースを、それらが動作するはずの言語で行いました。
コードトランスレータに関するさらなる記事を公開する予定です。次の記事では、具体的なC#の構造がC++の構造にどのようにマッピングされるかを詳しく説明します。別の記事ではメモリ管理モデルについて説明します。
読者からの質問にできる限りお答えしようと思います。コードトランスレータ開発の他の側面に興味を持つ読者がいれば、それについてさらに記事を書くことを検討します。