自作の汎用クラスが増えてくると、それをいちいち新しいプロジェクトに含めるのが、結構面倒な手間になってきます。
となると複数の機能をまとめて持たせてヘッダーファイルやソースファイル、そしてクラスを減らしたくなりますが、
新しいプロジェクトには
そしてそれが委託で受注したプログラムの場合、ソースコードの提出が要件であれば、 本来不要なコードまで開示してしまうことになりますし、 いくら注記をしたところで、クラスごと、あるいは関数や機能単位で流用されてしまう可能性があります。 それが(契約で禁止とした)流用であるかどうかは、証明することは難しいことでしょう。
そこでなんとかソースコードを隠す方法はないかと調査すると、静的ライブラリでいけそうでした。
C/C++ クラスを lib として提供する
不要なソースコードの開示を防ぐ目的で、C/C++ クラスをスタティックリンク ライブラリで定義・実装し、
それをうまく利用することができないか、実験・検討しています。
しかし、完全に満足いく形にはなりませんでしたので、今度は動的ライブラリ、DLL で試そうと思いました。
ここで利用している環境は、今のところは Windows 10、Visual C++ 2015 です。
うまく構築できれば、もっと便利な使い方もできそうです。
なお、本サイトのご利用に際しては、必ずプライバシーポリシー(免責事項等)をご参照ください。
投稿 July 28, 2023
ひとまず手近にある Visual C++ 2015 で、DLL から C/C++ クラスをエクスポートできるかを試します。
といっても、1 クラスを使うのに 1 DLL を作成するのは、最終的には嫌ですから、実現できるかのテストです。 実行ファイルを置くフォルダにたくさんの .dll ファイルがあるのは受け入れられません。
実現できたときには、複数のクラスを DLL に実装してソースコードを開示しない、という道ができることになります。
とにかく、提供するクラスの実装を行う DLL を作成していきましょう。
プロジェクトのタイプは「Win32 プロジェクト」を選びます。
DLL を作成したいので「アプリケーションの種類」で「DLL」を選びます。
また、「プリコンパイル済みヘッダー」のチェックは外しておきます。 必ずどうなる、というテストはしていませんが、そのほうが独立性が高まるのでは、と想像しています。
「完了」をクリックすると、プロジェクトが作成されます。
作成される DLL ファイル名はプロジェクト(ソリューション)と同じになりますから、 エクスポートするクラスの定義を行うヘッダーファイルも同名にしたいわけですが、 「ヘッダーファイル」には追加されていません。
ヘッダーファイルを作成します。
ヘッダーファイルだけを追加する方法が用意されていますが、どのように追加しても構いません。
追加したヘッダーファイルに、エクスポートするクラスを定義します。
「C/C++ クラスを lib として提供する」と同じように、 単純にメッセージボックスを表示するだけの関数 ShowMsg だけを定義しました。
ポイントは、class キーワードとクラス名の間に、 __declspec(dllexport) を入れておく、ということです。
続いて実装です。
実装は、特に気にするところもなく、普通に機能を実装するだけでよさそうです。
これでクラスを提供する DLL は OK ですので、x64 の Release 版としてビルドします。 32 ビット環境で利用したいときは x86 でビルドしましょう。
投稿 July 28, 2023
続いて今作成したクラスを利用するプログラムを作成しましょう。
呼び出し側の新しいプロジェクトを作成します。
簡単にテストするため、MFC 利用のダイアログアプリにします。 MFC をインストールしていないなどの場合には、Win32 アプリで「バージョン情報」を選んだときに実行することとすれば、 特にコードを変更することなくテストできます。
「ダイアログベース」を選んでおくと、OK ボタンがあるダイアログが作成されますので、 OK ボタンを押すと何か実行する、というコードで簡単にテストできます。
プロジェクトに取り込む必要があるものは、 ヘッダーファイルと .lib ファイルです。 実行時には、実行フォルダに .dll ファイルが必要になります。
ソリューションエクスプローラーでプロジェクトに lib フィルタを作成し、必要な 2 ファイルをプロジェクトに追加しました。
ここで lib を追加しなくてはいけませんから、異なるバージョンの VS でビルドした複数の lib があると、 きっとうまくいかない(リンクエラーになる)のでしょう。
では、OK ボタンのハンドラに DLL で定義したクラスを作成して関数を呼び出すコードを追加しましょう。
クラスを定義しているヘッダーファイルをインクルードします。
OK ボタン処理では、まず new 演算子で新しいクラスを作成し、 返されたポインタを使って、実装された関数を呼び出しています。 厳密には new で作成に失敗する可能性がありますので、戻された pClass が非 NULL であるチェックをすべきです。
使い終わったら削除します。
実行する前に、実行フォルダに .dll ファイルを配置しておく必要があります。
Visual Studio の開発環境からデバッグ実行する場合は、このように、 ソリューション名フォルダの中にあるプロジェクト名フォルダにコピーします。
ビルドも通り、実行すると無事にメッセージボックスが表示されました。
ということは、これで ShowMsg 関数のソースコードが隠された、ということになります。
しかし、とりあえず出来た、というところが重要であるということで・・・。
▼ 広告 ▼
古い Visual C++ プロジェクトから新しい環境に移行したとき、_sprintf でエラーが出る場合の回避方法について、書いています。
Visual C++ では、リストボックスの文字サイズをプロパティで変更することはできません。 ここでは自由な文字サイズに変更したり、別のフォントにしたりしています。
Windows PC で 2 台のモニタを接続している場合、2 台接続を検出し、座標を特定するためのコードについて書いています。
すでにインストールされている VS 2019 をアンインストールし、VS Community 2022 をインストールしなおしています。