私はJavaでかなり基本的なプログラミング経験があり、C++とPythonを試しました。Javaには理にかなっていますが、C++で記述した基本的なプログラムはWindowsとOSで問題なく動作しましたX.ソースファイルを他のコンピューターに送信し、コンパイルして実行することができたプログラムはかなり基本的なもので、ほとんどの場合、C++を学ぶためにやってきた基本的なオブジェクト指向のものだけです。
もちろん、どのマシンでもC++プログラムをコンパイルして問題なく実行することはできません。それはどの時点で起こりますか?プラットフォームはどのレベルの複雑さで問題になり始め、プログラムはどこでも実行されませんか?プラットフォーム固有のライブラリを使用するときですか?クロスプラットフォームライブラリを使用するだけで、プログラムをC++でクロスプラットフォームにできますか?
私はこれを自分で理解しようとしましたが、見つけたものはすべて頭に浮かぶか、単に質問に答えないかのどちらかです。考えられることの多くはエミュレーターまたはクロスプラットフォームの言語を尋ねる人々です。
クロスプラットフォームとモノプラットフォームの間の砂には非常に明確な線があります。
プログラムは、その上に構築された標準ライブラリによって公開されているAPIのみを使用しますか?
標準的な実装を対象とする場合、その標準を実装するプラットフォームは、理論的には、プログラムを正しくコンパイルして実行する必要があります。例外はたくさんありますが、一般的に巧妙なトリックを回避すれば、それらの例外の多くを回避できるはずです。
この問題が特にC++で発生するのは、長い間、C++標準ライブラリに重要なプログラムに役立つ多くのモジュールが含まれていないためです。並行性とGUIは2つの大きなものです。これは、C++標準ライブラリのみを使用して構築されたプログラムが、現代のソフトウェアに期待する機能の多くを備えていないことを意味しました。
標準ライブラリがサポートしていないものを実行するクロスプラットフォームソフトウェアをどのように作成しますか?
「クロスプラットフォームライブラリ」について言及しますが、実際には通常、その範囲に基づいて「フレームワーク」または「ツールキット」と呼ばれます。クロスプラットフォームのC++でソフトウェアを作成する方法は、標準ライブラリだけでなく、ターゲットプラットフォーム上に構築するフレームワークをターゲットにすることです。
基本的に、プラットフォーム固有のビットを別のライブラリに外部化することになります。たとえば、 wxWidgets は一般的なフレームワークです。そのクラスを使用して、GUIおよび関連機能(ファイルを選択するための標準ダイアログなど)を構築できます。内部では、条件付きコンパイルを使用して、各プラットフォームのネイティブGUIを使用してGUIを実装します。しかし、ライブラリのユーザーとして、それはあなたにとって重要ではありません。
歴史的注記:2015年のC++コンパイラーとライブラリーは、ほとんどの場合、非常に優れています。数年前に戻ると、それは真実ではありません。 C++は、その発足から何年も経過した1998年まで公式の標準を持っていませんでした。ベンダーがコンパイラとライブラリを更新して標準を正しく実装するには、長い時間がかかりました。ベンダー固有の拡張機能はたくさんあります(実際にはまだ存在しています)。一部のコンパイラには非標準のヘッダーと機能がありました。コードの移植性は事実上存在しませんでした。移植性の面でのC++の評判は依然として損なわれています。
プラットフォームはどのレベルの複雑さで問題になり始め、プログラムはどこでも実行されませんか?
基本的に重要なものは何でも。自明ではないプログラムを作成すると、willは、オーバーロードの順序付け、名前の検索、その他の複雑な処理を行うコンパイラ固有の方法に依存して、誤って終了します。さらに、標準では実際にはいくつかのコンテナ以外は何も提供されていないため、実質的にすべての重要なプログラムは非標準のプラットフォーム固有の動作に依存しています。
ただし、重要なプログラムは、別のプラットフォームへの移植がいかに簡単であるかによって大きく異なります。うまくプログラミングしてルールに固執していれば、かなり簡単に移植でき、ライブラリ(Boost.Filesystemなどのライブラリにすでに提供されている可能性があります)に部分を抽象化できればボーナスになります。
プログラムは主にveryプラットフォーム間での移植が困難になります。たとえば、特定の原子性/一貫性の保証を備えたディスクへのデータの書き込み、または独り言の場合intとポインタの間のキャストのように、そもそも本来すべきではなかった愚かなことをしました。
非常に簡単に言うと、プログラムをクロスプラットフォームにするのは、ある環境からソースを取得して別の環境でコンパイルし、完成した製品を期待どおりに機能させる能力です。
簡単に言えば、プログラムが利用可能であると期待しているものとターゲット環境が提供しているものとの間に完全な重複があります。環境固有のライブラリや動作が定義されていない言語機能を使用するなど、オーバーラップを100%未満にする操作を行うと、オーバーラップしない機能を提供できる環境にプログラムが関連付けられます。
(「プラットフォーム」は少しぎこちない言葉です。プラットフォームとしてのWindowsとUnix、またはプラットフォームとしてのLinux、OS X、BSD、Solarisはすべて名目上のUnixですが、人々は上記のいずれかをさまざまな環境で実行することができます。ハードウェアアーキテクチャや物事はさらに曖昧になります。それで私はWordを使い始めます。)
幸い、この問題を緩和するための基準があります。
言語。C++を作成しています。これは1998年にISOによって最初に標準化されました。その標準に準拠する任意のプログラムをコンパイルして実行できます。準拠するコンパイラとランタイムを備えたすべてのプラットフォームで期待される結果が得られます。標準から逸脱しない限り、プログラムのサイズや洗練度に制限はありません。おそらく標準に適合するプログラムが所定のプラットフォームで期待どおりに実行されない場合、そのプラットフォームでの言語の実装が疑わしくなります。多くの言語には、適合性の検証に使用できる慎重に設計されたテストスイートがあります。
Javaは、言語を標準化するだけでなく、オブジェクトコードも標準化するため、特筆に値します。これにより、プログラムを再コンパイルせずにどこでも実行できるようになります。これは、オブジェクトポイントを実行できるプラットフォームカスタマイズされた仮想マシン(またはハードウェア)に追加のレイヤーを押し下げて、適合点を押し下げることによって実現されます。
API。プログラムに特定の処理を実行させるために行う呼び出しも、標準化することができます。言語と同様に、これらのAPIとそれらを実装するライブラリは、特定のプラットフォームに適した基盤となる実装を使用して呼び出し元が期待するとおりに動作するように設定できます。そのようなAPIの1つは、IEEEの [〜#〜] posix [〜#〜] 標準です。これは、1980年代にUnixで起こっていた断片化を阻止する方法として生まれました。 (私はその頃でした。その側面は面白くありませんでした。)標準の呼び出しと動作を定義することにより、システムベンダーは、OSへの移行が、過去。 POSIXは広く採用され、ほぼ30年経った今でも広く使用されています。
複数のプラットフォームで実行する必要があることを知っていたので、標準に厳密に準拠したプロジェクトを数多く行ってきました。私がトラブルに遭遇したのは、実行する予定のあらゆる場所で機能するコードであり、実行しなかったいくつかの場所でうれしい驚きを覚えました。
基本的に、プログラムの外で何かに「触れる」とき。 1つの特定のケース(私はあえて唯一のケースとは言いません)は、オペレーティングシステムに関連するライブラリを使用する場合です。プロセス間で共有メモリを使用することや、コンソールに凝ったものを印刷することなど。最初のケースでは、オペレーティングシステムによって処理されているメモリにアクセスします。2番目のケースでは、画面もオペレーティングシステムによって制御されます。
GUIの実行はOSに依存しますが、クロスプラットフォームに作成されたGUIライブラリがあるため、そのことを心配する必要はありません。少なくとも理論的には。
クロスプラットフォームになるために重要なものを作るのは難しいです。良い点は、適切なライブラリを使用して適切なテストを行っても、少なくともコードが大きすぎない場合は、ソフトウェアを移植可能にすることはそれほど難しくないということです。大きさが大きすぎるかどうかは、チームのサイズ、プログラミングの専門知識などに依存します。