アプリケーションとプロジェクトにC++を使用することの多くの大きな利点の1つは、膨大なC++ライブラリやフレームワークを利用できることです。基本的に、あらゆるものに対応するC ++ライブラリが用意されていますし、存在しない場合は、間違いなくCのライブラリが用意されています。
その昔、C++コンパイラの互換性の違いから、さまざまなライブラリをC++プロジェクトに統合するのは大変なことでした。GCCで作られたプロジェクトはVC++でコンパイルするのが難しく、VC++で作られたプロジェクトはBCCでコンパイルするのが難しい..といった具合です。とても喜ばしいことに、当時と比べて随分と進歩して、今ではC++コンパイラ同士の互換性はかなりのレベルに達しています。
C++BuilderではClangを使用していますが、これも例外ではありません。従来のBorlandンパイラは最新のC++構文に対応しておらず、問題があることが多いのですが、Clangコンパイラは最も標準に準拠したC++コンパイラの1つで、C++BuilderプロジェクトにC++ライブラリの広大な世界を提供します。
これは、簡単だという意味ではありません。どんなライブラリでも、プロジェクトで使用するためには、必ずいくつかのコツや調整が必要ですが、以前に必要だったことと比較すると、とても簡単です。
このブログ記事では、ごく一般的なC++ライブラリであるSQLiteCppをC++Builderプロジェクトで動作させるために必要なことを探っていきます。
Table of Contents
SQLiteCppとは?
SQLiteCppは,CライブラリであるSQLiteデータベースのC++RAIIラッパーであり,このほぼユニバーサル(世界共通)なポータブルリレーショナルデータベースライブラリに対する優れたC++インタフェースを提供します。
SQLiteは、組み込みプロジェクトからメインストリームアプリケーションに至るまで、さまざまな種類のデータを保存、クエリ、取得するための使いやすい統合データベースとして、さまざまなアプリケーションで使用されています。
今回はSQLiteCppを使って、C++Builderのシンプルなコンソールアプリケーション内でいくつかのデータを保存したり取得したりする簡単なアプリケーションを作成します。
TwineCompileの使用
TwineCompileは、C++Builderのコンパイル時間を大幅に短縮するソリューションで、C++Builder IDEに直接統合され、マルチスレッド、ファイルキャッシュ、自動バックグラウンドコンパイルなどの技術を活用することで、コンパイル/メイク/ビルド時間を劇的に削減します。
TwineCompileを利用すると、これまでビルドが遅かったClangコンパイラ(bcc64、bcc32c)に比べてビルド速度が向上します。
TwineCompileの詳細は、以下のブログをご覧ください。
- 大規模なC++プロジェクトのビルド時間をTwineCompileで高速化
- 新たにアップデートされたTwineCompileでC++のコンパイル速度をスピードアップ – GetItで入手可能に!
- 16コアのRyzen 9 5950xを使用して100万行のC++コードを2分未満でコンパイルする
このブログでは、TwineCompileをインストールした状態でC++Builder IDEと一緒に使用していきますが、インストールしなくてもSQLiteCppのプロジェクトのコンパイルは可能です。ただ、表示されるダイアログ画面の表示は、TwineCompileの利用有無によって変化します。ここでは、TwineCompileを利用する前提で話を進めていきます。
SQLiteCppライブラリの取得
SQLiteCppはGithubにホストされており、リポジトリにはアプリケーションをコンパイルするために必要なファイルがすべて含まれています。
(1) https://github.com/SRombauts/SQLiteCppに移動します。
(2) SQLiteCppの最新版をダウンロードし、SQLiteCpp-master.zipファイルを任意のフォルダに解凍します。
プロジェクトの設定
SQLiteCpp は CMakeビルドシステムをサポートしているので、それを使って C++Builder でライブラリをビルドすることもできますが、自分でプロジェクトを作成した方が面白くて直接的な場合が多いです。これには、用途に合わせてビルドをカスタマイズできるという利点もあります。
(3)この手順は、任意のパスに展開したSQLiteCpp-masterフォルダ内にcbuilderというディレクトリを作成します。ここには、C++Builder固有のプロジェクトファイルが格納します。そのディレクトリ構造は下図のようになります。
(4)このライブラリをC++Builder アプリケーションにリンクできるように静的ライブラリとして構築したいので、RAD Studioで新しい静的ライブラリプロジェクトを作成します。
そしてこのプロジェクトをcbuilderディレクトリ内にsqlitecpp.cbprojという名前のプロジェクトとして保存します。
(5)プロジェクトオプションの[すべての構成]でClangコンパイラを有効にします。
(6)ライブラリアンの設定で、「ページサイズ」を64に設定します(これは経験に基づいています。使用するページサイズがわからない場合は、プロジェクトのビルド時にページサイズを調整する必要があるかどうかをTLIBリンカによって通知されます。)
ソースファイルの選択
プロジェクトの設定が完了したところで、コンパイルに必要なソースファイルをプロジェクトに追加する必要があります。インクルードするファイルの決定方法はプロジェクトごとに異なり、適切なファイルを決定するためにいくつかの調査が必要になる場合があります。SQLiteCppフォルダ内のCMakeLists.txtには、その助けとなる役立つ情報が記載されています。以下のガイドラインを参考にしてください。
- SQLiteCpp内のsrcディレクトリを探します。拡張子が.c、.cpp、または.cxxのファイルがソースファイルになります。
- main() メソッドを含むファイルを無視します。 これらは通常、スタンドアロンアプリケーションを対象としたテスト、デモ、またはサンプルファイルです。
SQLiteCppでは、以下がソースファイルに該当します。
- sqlite3/sqlite3.c
- src/Transaction.cpp
- src/Backup.cpp
- src/Column.cpp
- src/Database.cpp
- src/Exception.cpp
- src/Statement.cpp
(7) 上記のファイルをプロジェクトマネージャで追加します。
ライブラリの構築
ブロジェクトをビルドすると、以下のようなエラーが発生します。
この問題を解決するためには、プロジェクトオプションのインクルードパスを追加する必要があります。
(8)インクルードパスを設定します。プロジェクトには、srcファイルと同じ階層にincludeディレクトリがあることにお気づきでしょうか。このフォルダをプロジェクトのインクルードパスに追加して、ヘッダを検索できるように設定します。
(9)プロジェクトをビルドします。今度は下図のように正常にビルドが完了するはずです。これでSQLiteCppの静的ライブラリの完成となります。
ライブラリの利用
さて、ライブラリができたので、簡単なアプリケーションを作って試してみましょう。
(10)同じプロジェクトグループに新しいC++コンソールアプリケーションを作成します。
コンソールアプリケーションのターゲットフレームワークとして”ビジュアルコンポーネントライブラリ”を選択し、VCLでこのライブラリの動作を確認します。
(11)このプロジェクトをtest_sqlite.cbprojとしてcbuilderフォルダに保存する
(12) コンソールアプリケーションのプロジェクトの「プロジェクトオプション」で、このプロジェクトのインクルードパスとして「.include」を追加し、SQLiteCppライブラリで行ったのと同様に、CLANGコンパイラを有効にします。
(13)コンソールアプリケーションのプロジェクトのmainルーチンを持っているC++ソースファイル(例えば、File1.cpp)を以下のように修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <vcl.h> #include <windows.h> #pragma hdrstop #pragma argsused #include <tchar.h> #include <stdio.h> #include <conio.h> #include <SQLiteCpp/SQLiteCpp.h> #pragma link "sqlitecpp.lib" int _tmain(int argc, _TCHAR* argv[]) { return 0; } |
注意: #pragma linkディレクトリを使用して、ライブラリプロジェクトからsqlitecpp.libライブラリをリンクする必要があることをコンパイラに伝えています。代わりに、.libファイルをテスト・プロジェクトに追加することもできますが、#pragma linkを使用すると、より簡単になります。
(14) データベースを作成し、データを挿入し、再びデータを読み出すコードを追加するために、mainルーチンを以下のように修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
int _tmain(int argc, _TCHAR* argv[]) { // Open a database file in create/write mode SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); std::cout << "SQLite database file " << db.getFilename().c_str() << "¥n"; // Create a new table with an explicit "id" column aliasing the underlying rowid db.exec("DROP TABLE IF EXISTS test"); db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"); // first row db.exec("INSERT INTO test VALUES (NULL, 'test')"); // second row db.exec("INSERT INTO test VALUES (NULL, 'second')"); // update the second row db.exec("UPDATE test SET value='second-updated' WHERE id='2'"); // Check the results : expect two row of result SQLite::Statement query(db, "SELECT * FROM test"); std::cout << "SELECT * FROM test :¥n"; while (query.executeStep()) { std::cout << "row (" << query.getColumn(0) << "," << query.getColumn(1) << ")¥n"; } getch(); return 0; } |
(15)最後に、プロジェクトをビルドして実行し、ライブラリが動作していることを確認します。(下図は、その実行結果です)
まとめ
このように、Clangコンパイラを搭載したC++Builderでは、プロジェクトに統合できるさまざまなライブラリやフレームワークの可能性が広がります。このオープンソースのC++ライブラリをコンパイルしてC++Builderアプリケーションで動作させるために、コードを一度も変更する必要はありませんでした。
他にも何千ものC++プロジェクトが存在しますので、是非ご自身ののC++プロジェクトで使用してみることを強くお勧めいたします。
また今回のブログで紹介しましたTwineCompileを利用すると、非常に時間がかかっていたC++プロジェクトのビルドを現在の半分、もしくは4分の1、さらにはプロジェクトのコンパイル速度が50倍になったという報告もあります。今回取り上げたSQLiteCppプロジェクトはソースが小さいため、TwineCompileの有無によって速度にあまり違いは感じませんが、オープンソースのC++プロジェクトの中には膨大なソースファイル数のライブラリも存在します。このようなケースではTwineCompileを利用することによってそれらのビルド時間を大幅に節約できるかもしれません。
もし興味がございましたら、実際にご自身でビルド速度を体感してみてください!!
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition