私はC++プログラムを作成しています。
C ++での私の最大の悩みの1つは、想定されるプラットフォームの独立性です。
おそらく、WindowsでLinux C ++プログラムをコンパイルし、WindowsプログラムをLinuxにコンパイルすることは、大量の不可解なエラーとプラットフォーム固有のインクルードファイルなしではほとんど不可能であることをご存知でしょう。
もちろん、Cygwinやwineのようなエミュレーションにいつでも切り替えることができますが、他に方法はありませんか?
言語自体はクロスプラットフォームですが、ほとんどのライブラリはそうではありませんが、C ++でプログラミングするときに完全にクロスプラットフォームにしたい場合は、3つの点に注意する必要があります。
まず、 SConsのようなある種のクロスプラットフォームビルドシステムの使用を開始する必要があります。次に、使用しているすべてのライブラリがクロスプラットフォーム用に構築されていることを確認する必要があります。そして、マイナーな3番目のポイントとして、すべてのターゲットプラットフォームに存在するコンパイラを使用することをお勧めします。ここでは、gccを念頭に置いています(C ++はかなり複雑な獣であり、すべてのコンパイラには固有の癖があります)。
グラフィカルユーザーインターフェイスに関するいくつかの提案があります。使用できるこれらのいくつかがありますが、最も注目すべき3つは次のとおりです。
GTK +とQTは独自のウィジェットセット(ボタン、リストなど)が付属する2つのAPIですが、wxWidgetsは現在実行中のプラットフォームのネイティブウィジェットセットのラッパーAPIです。つまり、前者の2つはシステムの他の部分と比べて少し異なって見える可能性がありますが、後者はネイティブプログラムのように見えます。
また、ゲームプログラミングに興味がある場合は、同じように多くのAPIから選択でき、それらはすべてクロスプラットフォームでもあります。私が知っている最も完全な機能を備えた2つは次のとおりです。
どちらにも、プラグインまたは組み込みのいずれかを介して、グラフィックスから入力およびオーディオルーチンまですべてが含まれています。
また、C ++の標準ライブラリが少し不足していると感じた場合は、Boostをチェックして汎用のクロスプラットフォームの甘さを確認してください。
幸運を。
C++はクロスプラットフォームです。あなたが抱えていると思われる問題は、プラットフォームに依存するライブラリを使用していることです。
あなたが本当にUIコンポーネントについて話していると思います-その場合、GTK +、Qt、またはwxWindowsのようなものを使用することをお勧めします-それぞれに異なるシステム用にコンパイルできるUIコンポーネントがあります。
唯一の解決策は、プラットフォームに依存しないライブラリを見つけて使用することです。
また、補足として、cygwinもWineもエミュレーションではありません。これらは、それぞれのシステムで見つかった同じ機能の100%ネイティブ実装です。
落とし穴に気づいたら、実際にはそれほど難しくありません。私が現在取り組んでいるすべてのコードは、32 ビットと 64 ビットの Windows、Linuxのすべてのフレーバー、および Unix (Sun、HP、および IBM) でコンパイルされます。明らかに、これらは GUI 製品ではありません。また、自分でコンパイルしない限り、サードパーティのライブラリは使用しません。
コンパイラ固有のコードをすべて含む .h ファイルが 1 つあります。たとえば、Microsoft と gcc は、8 ビット整数の指定方法について意見が一致していません。だから.hで、私は持っています
#if defined(_MSC_VER)
typedef __int8 int8_t;
#elif defined(__unix)
typedef char int8_t;
#endif
特定の下位レベルの関数呼び出しを統一するかなりの量のコードもあります。次に例を示します。
#if defined(_MSC_VER)
#define SplitPath(Path__,Drive__,Name__,Ext__) _splitpath(Path__,Drive__,Dir__,Name__,Ext__)
#elif defined(__unix)
#define SplitPath(Path__,Drive__,Name__,Ext__) UnixSplitPath(Path__,Drive__,Name__,Ext__)
#endif
この場合、UnixSplitPath() 関数を作成する必要があったと思います。必要な場合もあります。しかし、ほとんどの場合、正しい置換関数を見つける必要があります。私のコードでは、どちらのプラットフォームでもネイティブ関数ではありませんが、SplitPath() を呼び出します。#defines は私のためにそれを整理します。自分を鍛えるには時間がかかります。
信じられないかもしれませんが、私の .h ファイルの長さはわずか 240 行です。それほど多くはありません。これには、エンディアンの問題の処理も含まれます。
低レベルのものの中には、条件付きコンパイルが必要なものがあります。たとえば、Windows ではクリティカル セクションを使用しますが、Linux では pthread_mutex を使用する必要があります。CriticalSection はクラスにカプセル化されており、このクラスにはかなりの条件付きコンパイルがあります。ただし、上位レベルのプログラムはまったく意識しておらず、クラスはプラットフォームに関係なくまったく同じように機能します。
もう 1 つの秘訣は、すべてのプラットフォームで頻繁に (特に最初に) プロジェクトをビルドすることです。コンパイラの問題を芽で摘むと、はるかに簡単になります。クロスプラットフォームを試みる前に、開発が完了するまで待たないでください。
クロスプラットフォームである ANSI C++ とライブラリに固執すれば、問題ないはずです。
プロジェクト内のすべてのプラットフォーム固有のコードを含む低レベル レイヤーを作成します。このレイヤーの 2 つのバージョン (Windows 用と Linux 用) を同じインターフェイスで実装し、それらを 2 つのライブラリにビルドします。そのインターフェイスを介して、プロジェクト内のすべてのプラットフォーム固有の機能にアクセスします。
このレイヤーには、ファイル アクセス、印刷、GUI などの一般的なクラスを含めることができます。
そのレイヤーを使用するすべての (プラットフォーム固有ではない) コードは、Windows で 1 回、Linux で 1 回コンパイルできるようになりました。
Windowでコンパイルし、Linuxで再度コンパイルします。プラットフォーム固有のライブラリを使用していない限り、機能するはずです。一度コンパイルすればどこでも動作するJavaとは異なります。C ++用の仮想マシンを作成した人は誰もいませんし、おそらく作成することもありません。C ++で記述したコードは、どのプラットフォームでも機能します。最初にすべてのプラットフォームでコンパイルする必要があります。
提案:
intsにはtypedefを使用します。または#include<stdint.h>。一部のマシンは、intが8バイト、一部が4バイトであると考えています(以前は2バイトと4バイトでした。時代はどのように変化しましたか。)
可能な限りカプセル化を使用してください。私の最後のウィンドウのコンパイラは、%lldは%I64d "であると考え、vsnprintf()の厄介な戻り値、close()やソケットに関する同様の問題などを示しました。
スタックサイズ/バッファサイズの制限に注意してください。他の問題の中でも、Windowsで8kのUDPバッファ制限に遭遇しました。
何らかの理由で、私のWindowのC ++コンパイラは、スタックからの動的なサイズの割り当てを受け入れませんでした。例:void foo(int a){int b [a]; }そのようなことに注意してください。再コーディングする方法を計画します。
#ifdefはあなたの親友になることができます。そしてあなたの最悪の敵!(同時に!)
それは確かに行うことができます。しかし、コンパイルしてテストするのは早い段階で頻繁に行ってください。
また、Linux と Windows ではデータ モデルが異なります。記事を参照してください: 64 ビット プログラム開発の忘れられた問題
標準のC++は、どのプラットフォームでもエラーなしでコードをコンパイルします。WindowsでBloodshedDevC ++を使用してみてください(VC ++ / Borland C ++の代わりに)。
Bloodshed Dev C++はC++標準を確認しているため、それを使用してコンパイルされたプログラムは、ほとんどの場合、エラーなしでLinux上でコンパイルされます。