4

クロスプラットフォーム ライブラリを作成しているとします。プラットフォームごとに異なる動作があり、この動作 (または定義) がライブラリがあるプラットフォームに基づいてコンパイル時に選択されるようにコードを整理する必要があります。コンパイル中。

C++ でこれを行う「通常の」方法は#ifdef、メソッドまたはクラスを作成するときにコードを大量に汚染することです。

アプローチの問題は次のとおりです。

  • ソースコードは本当に醜い
  • 3 つのプラットフォームをサポートしている場合、ソース コードは実際に必要なものよりも約 3 倍大きくなります。#ifdef
  • 異なる実装の間に実際の違いはありません。コード ベースが成長しているときは維持するのが難しく、単純に 3 ~ 4 のプラットフォームしかない場合、それは非常に急速に成長します。

C++11 には多くの新機能があるため、何かが変更されているかどうか、またそのための新しいオプションがあるかどうか疑問に思っていました。

4

1 に答える 1

6

これを行うには、ビルド システムを使用する必要があります。プラットフォームに依存しない関数の宣言とクラスの定義を含むヘッダーを提供する必要があります。次に、ターゲット プラットフォームに応じて、ビルド システムはそれらの関数とクラスの適切な実装をコンパイルする必要があります。

たとえば、グラフィックや GUI 要素を表示するためのウィンドウの作成を考えてみましょう。これを行うためにライブラリを使用していない場合は、クロスプラットフォーム コードを自分で作成する必要があります。まず、プラットフォームに依存しないインターフェイスがどうあるべきかを正確に考える必要があります。おそらく、windowクラスといくつかのヘルパー関数があります。次に、そのクラスの定義とヘルパー関数の宣言をヘッダー ファイルに提供し、プラットフォームごとに個別の実装を提供できます。次に、次のような一連のファイルが作成されます。

  • window.h
  • window_wayland.cpp
  • window_winapi.cpp
  • window_x11.cpp

これで、クラスと関数を使用する必要があるすべてのファイルは、#include <window.h>. それらはすべて同じ関数宣言を取得します。ただし、window_x11.cppX11 ウィンドウ システムをwindow_wayland.cpp使用するシステム、Wayland を使用するシステム、およびwindow_winapiWindows でコンパイルするビルド システムの構成を指定します。これは、構築しているプラ​​ットフォームに応じて、ターゲット プラットフォームで動作するヘッダーの実装を取得することを意味します。

これにはいくつかの利点があります。

  1. ビルドの懸念 (ビルド対象のプラットフォーム) をコードの懸念から分離しました。
  2. プラットフォームに依存する各実装には、独自のファイルがあります。
  3. プリプロセッサ ディレクティブで雑然としたファイルや、実行パスをたどるのが難しいファイルはありません。

これは、定義を使用してコードのさまざまな部分を選択的にコンパイルすることに問題があるという意味ではありません。私は、プラットフォームに依存する部分にローカライズされた少量のコードでのみこれを確認することを好みます。理想的には、プラットフォームに依存するコードを関数でラップ#ifdefし、実装を交換するだけです。

この選択的なビルドを正確に行う方法は、使用しているビルド システムによって異なります。GNU ビルド システムでは、automake を使用して条件付きコンパイルを実現できます。ドキュメントにいくつかの例が示されています。与えられた簡単な例は次のとおりです。

bin_PROGRAMS = hello
if LINUX
hello_SOURCES = hello-linux.c hello-common.c
else
hello_SOURCES = hello-generic.c hello-common.c
endif

automakeこの構成で実行すると、適切なメイクファイルが生成されます。

于 2013-04-06T09:55:40.967 に答える