__declspec

前回は、__declspec(dllexport)として外部参照可能な関数として宣言し、GetProcAddressで関数ポインタを取得し、関数を呼び出すことができた・・・。

__declspecは、Microsoft独自の拡張属性構文で属性にはdllexport以外にもいろいろある・・・。

__declspec ‐ 通信用語の基礎知識

例えば、dllimportを使えば、GetProcAddressによる関数ポインタ取得なしに関数を呼び出すことができる・・・。

__declspec(dllimport) を使ったアプリケーションへのインポート

まず、__declspec_1プロジェクトを作るのだが、

f:id:BG1:20151103094254p:plain

全体のソリューション名を__declspecにしておく・・・。

__declspec_1.cppは、

DllFuncが"DllFunc 1!"と出力するようにしておく・・・。

次に、__declspec_2プロジェクトを追加し、__declspec_2.cppは、

DllFuncが"DllFunc 2!"と出力するようにしておく・・・。

Mainプロジェクトを追加し、Main.cppに呼び出す側の処理を書く・・・。

__declspec(dllimport)で宣言すれば、GetProcAddressなしに呼び出し側から参照できる・・・。

f:id:BG1:20151103100631p:plain

[ビルド]-[構成マネージャ]で、

f:id:BG1:20151103100817p:plain

[新規作成]で新しいビルド構成を作る・・・。

f:id:BG1:20151103102726p:plain

"Release"をベースに、"__declspec_1 Release"という構成を作成・・・。

f:id:BG1:20151103101118p:plain

__declspec_2はビルドしないという構成・・・。

そして、

f:id:BG1:20151103101217p:plain

ここでは[プロジェクト依存関係]で__declspec_1をチェックする・・・。
(__declspec_2はビルドしないのでチェック不要・・・。)

これで、

f:id:BG1:20151103101448p:plain

"__declspec_1 Release"を選択して、ビルド・・・。

f:id:BG1:20151103101703p:plain

Main.exe、__declspec_1.dllができる・・・。

実行すると、

DLL_PROCESS_ATTACH
DllFunc 1!
DLL_PROCESS_DETACH
続行するには何かキーを押してください . . .

と直接DllFuncを呼び出せる・・・。

同様に、__declspec_2も、

f:id:BG1:20151103102917p:plain

"__declspec_2 Release"という__declspec_1をビルドしない構成を作って、

f:id:BG1:20151103103049p:plain

依存関係も__declspec_2だけチェック・・・。

DLL_PROCESS_ATTACH
DllFunc 2!
DLL_PROCESS_DETACH
続行するには何かキーを押してください . . .

"DllFunc 2!"が出力された・・・。

さて、この2つのDLLは差し替え可能なのだろうか?
それぞれビルドしている構成も違うので、別々にリンクしてるように感じるかもしれない・・・。
そこで、

f:id:BG1:20151103104208p:plain

出力するDLLのファイル名を、<プロジェクト名>.dllから、

f:id:BG1:20151103104233p:plain

<ソリューション名>.dllに変更・・・。

こうすると、__declspec_1も__declspec_2も、__declspec.dllになる・・・。
両方ビルドした後、__declspec_2 releaseにある__declspec.dllをコピーして、__declspec_1 releaseにある__declspec.dllに上書き・・・。

これで__declspec_1 releaseのMain.exeをコンソールから実行すると、

C:\Project\Cloud\github.com\Sample\winapi\__declspec\__declspec\src\__declspec\__declspec_1 release>Main.exe
DLL_PROCESS_ATTACH
DllFunc 2!
DLL_PROCESS_DETACH

C:\Project\Cloud\github.com\Sample\winapi\__declspec\__declspec\src\__declspec\__declspec_1 release>

__declspec_2のDllFuncがちゃんと呼ばれてる・・・。
ということで、ここで生成されたDLLはちゃんと差し替え可能になっている・・・。

Sample/Main.cpp at master · bg1bgst333/Sample · GitHub
Sample/__declspec_1.cpp at master · bg1bgst333/Sample · GitHub
Sample/__declspec_2.cpp at master · bg1bgst333/Sample · GitHub