C++Builder 64 ビット Windows 版の相違点
C++Builder 64 ビット Windows アプリケーションの開発 への移動
BCC64 とその直接の前身である BCC32 の違いの概要については、「BCC64 と旧世代の C++ コンパイラの違い」を参照してください。 BCC64 は、DOS および 16 ビット Windows 以降の C/C++ 開発の込み入った歴史と深く関係し合うコンパイラの系統における最新のものです。
既存の 32 ビット C++ プロジェクトを 64 ビット Windows に移植する具体的な手順については、「既存の C++ プロジェクトを 64 ビット Windows にアップグレードする」を参照してください。
目次
32 ビット Windows アプリケーションと 64 ビット Windows アプリケーションの違い
64 ビット開発への移行については、特に C++ および Windows に関係する場合は、インターネットでも広く扱われています。 詳細については、以下のトピックを参照してください。
ここでは特に 2 つの基本的な概念を取り上げます。
size_t か unsigned か
size_t
は符号なしの整数型として定義されているもので、malloc
に引数として渡され、sizeof
の結果にもなります。メモリ/データ モデルで可能な最大のオブジェクトのサイズを表せるだけの十分なビット数があります。 Win32 と Win64 では、これはポインタと同じサイズです。 ちなみに、これら現代の Windows メモリ モデルはフラットです。 それに対して、DOS のセグメント化されたラージ メモリ モデルでは、ポインタは 32 ビットでしたが、最大のオブジェクトは 64KB でした。 そのため、size_t
があれば 16 ビットだったでしょう。
Win32 の "ILP32" データ モデルでは、int
(および long
)とポインタは 32 ビットです。 size_t
の代わりに unsigned int
を使用することはできますが、それでは移植可能ではなくなります。
Win64 は "LLP64" データ モデルです。つまり、long long
とポインタは 64 ビットであるのに対して、int
(および long
)はまだ 32 ビットです。 そのため、size_t
を使用する必要があります。
_WIN32 が Win64 にも定義
_WIN32 は Win32 ターゲットと Win64 ターゲットの両方に(整数 1 として)定義されています。 これにより、プログラムが特に(現代の)Windows プラットフォーム一般をターゲットにすることができます。
_WIN64 は Win64 ターゲットにのみ定義されています。_WIN32 も定義されているため、たとえば以下のように _WIN64 を先に確認します。
#if _WIN64
// 64-bit Windows
#elif _WIN32
// 32-bit Windows
#elif __APPLE__
// macOS
#else
#error Not a supported platform
#endif
OLE_HANDLE の長さは 64 ビット Windows でも 32 ビット
Win64 では HANDLE 型のサイズが 64 ビットに変わりましたが、OLE_HANDLE は例外で、現在は Win64 でも 32 ビットです。 これは、OLE_HANDLE と他の HANDLE 型が交換可能であると想定しているコードをすべて変更しなければならないことを意味します。 「http://stackoverflow.com/questions/401812/what-is-the-proper-way-to-cast-from-an-ole-handle-to-an-hicon」も参照してください。
コンパイラの相違点
BCC64 は Clang コンパイラ フロントエンドをベースにしています。 参照:
#include
windows.h
64 ビット Windows C++ アプリケーションには、必ず以下の行が含まれていなければなりません。
#include <windows.h>
BCC32 では windows.h のインクルードは必須ではありませんが、BCC64 では windows.h が必須であり、他のあらゆる Clang 拡張 C++ コンパイラと同様に、#include
についてより厳密な扱いがなされます。
64 ビット パッケージの生成をサポート
XE6 リリースより、BCC64 では 64 ビット Windows パッケージ(.bpl
ファイル)を生成するようになりました。また、64 ビット Windows 用パッケージに静的にリンクすることもでき、C++Builder 64 ビット Windows でパッケージを使用することができます。
C++Builder では Mac 用の .dylib ファイルや iOS および Android プラットフォーム用のパッケージを生成しないことに注意してください。 これらのプラットフォームの場合は、静的ライブラリを使用できます。
Win32 パッケージと Win64 パッケージの相違点
Win64 の場合、PACKAGE と指定されているコード要素が現在のトランスレーション ユニットに定義されていれば、コンパイラではそれらのコード要素をエクスポートします。 クラスの場合、メンバでないコード要素が 1 つでも定義されていれば、そのクラスはエクスポートされます。 定義が見つからなければ、コンパイラはそのコード要素をインポートされるものとして扱います。 この動作は Win32 の場合とは異なります。
Win32 と Win64 のどちらの場合も PACKAGE を使用する必要がありますが、Win64 では定義が存在する場合にのみエクスポートします。 この要件は、パッケージを使用する側に公開されることになっている変数、関数、クラスに適用されます。
例:
class PACKAGE TTest : public System::TObject {
private:
int FProp;
__property int Prop = {read=FProp, write=FProp};
public:
__fastcall TTest(void);
__fastcall virtual ~TTest(void);
};
PACKAGE bool GoodieFlag;
PACKAGE void __fastcall SuperFunc(const System::UnicodeString S);
概要については、「パッケージのビルド」を参照してください。
Win64 パッケージの要件
- パッケージからコンポーネント クラスをエクスポートするには、コンポーネントごとに非インライン メンバが少なくとも 1 つ必ず存在するようにしなければなりません(これは、[ファイル|コンポーネントの新規作成]ウィザードで行われます)。
- 以前、[パッケージの出力ディレクトリ]を設定して Win32 パッケージを生成した場合は、[ツール|オプション...|環境オプション|C++ オプション|パスとディレクトリ(C++)]ページで Win64 プロジェクトの場合のパスを必ず変更して、Win32 パッケージが上書きされないようにします。 [パッケージの出力ディレクトリ]がオーバーライドした場合は、[プロジェクト|オプション...|C++ (共有オプション)]で[最終出力ディレクトリ]が正しく設定されているかどうかを確認できます。 つまり、[最終出力ディレクトリ]は Win32 の場合と Win64 の場合とで異なる必要があります。
デバッグ機能
「C++Builder 64 ビット Windows アプリケーションのデバッグ」を参照してください。