DLL関数を作成する(引数なし)|C++でDLLを自作してExcelVBAで呼び出す方法②
前回、何も処理を行わない「EmptyProcess」関数の入った「VBA_DLL.dll」を作成しました。
しかし、VBAで呼び出したときに何も起きないので成功しているかが少しわかりづらかったです。
そこで今回は視覚的にも呼び出したことがわかるような処理をする関数を新たに作成していきます。
今回も前回に引き続き、引数なし&戻り値なしのDLL内だけで完結する関数を作成します。
作成する関数は新たなDLLファイルを作成するのではなく、前回と同じ「VBA_DLL.dll」内に追加していきます。DLLファイルは1つのファイルに複数の関数をまとめることができるので、今回はその方法も合わせて解説していきます。
DLLファイルを作成(引数なし)
前回、VBAで呼び出し可能なプロジェクトを作成したのでそのプロジェクトをそのまま使い回します。
Visual Studioを閉じてしまった場合は前回作成したフォルダの「VBA_DLL.sln」を開いて下さい。
今回は引数なしの関数として「”Hello World”という文字列をメッセージボックスで表示するHelloWorld関数」を前回のDLLファイル内に追加していきます。
(※ 処理内容としては表示する文字列が定数であるVBAのMsgBox関数と同じです)
ヘッダーファイル (VBA_DLL.h)
今回は新規の関数を作っていくので、その関数の宣言をヘッダーファイルに追記します。
関数宣言は前回も解説した通りで、下記のように書きます。
引数はないので括弧内は空白にし、戻り値もないので型は「void」とします。
extern “C” VBADLL_API void HelloWorld();
1つのDLLファイルに複数の関数を作成する場合は、上画像のように作成する関数をすべて宣言しておく必要があります。ソースファイル(.cpp)側で関数の処理内容を書くまでは緑の波線(警告)が表示されますが無視してOKです。
ソースファイル (VBA_DLL.cpp)
ヘッダーファイルに新たな関数「HelloWorld」の宣言をしたので、ソースファイル(.cpp)側では関数の処理内容を書いていきます。コードは下記の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include "VBA_DLL.h" #include "windows.h" //MessageBox関数が含まれている //void EmptyProcess() は表示の関係上省略 void HelloWorld() { MessageBox(NULL, TEXT("Hello World"), TEXT("DLL"), MB_OK); return; } |
このコードにより「Hello World」という文字列が「DLL」というキャプションのメッセージボックスで表示することができます。このメッセージを表示するために使っているMessageBox関数はWindows APIのものなので、VBAで直接呼び出すことも可能です。
MessageBox関数の引数等の詳細は下記のMicrosoftページを参照下さい。
MessageBox function (winuser.h) – Win32 apps | Microsoft Docs
C++ではVBAでいうところのMsgBox関数のようなメッセージボックスを表示する関数が存在しないため、Windows APIのMessageBox関数を呼び出すのが一般的です。
C++でWindows APIを使う場合は「windows.h」をインクルードする必要があります。
「#include “windows.h”」の1文を書いておかないと使用できないので注意しましょう。
(※MessageBox関数自体はwindows.h内に含まれているwinuser.h内にあります)
VBAで作成したDLLファイルを呼び出す
上記のコードでDLLファイルを出力したら、VBAで呼び出してみます。コードは下記の通りです。
1 2 3 4 5 6 7 |
'DLLファイルの関数定義 Private Declare PtrSafe Sub HelloWorld Lib "C:\programming\cpp\VBA_DLL\x64\Release\VBA_DLL.dll" () Sub Test() Call HelloWorld End Sub |
上記コードを実行することで、下画像のようなメッセージを表示させることができます。
しっかりとDLLファイルの処理を呼び出せていることが視覚的にも確認することができます。
ちなみにDLLファイルの関数を呼び出したときのVBA側の処理についてですが、DLLファイル側の処理が終わるまでVBA側の処理は止まっている状態です。たとえば上記の「Call HelloWorld」以降に処理を書いた場合は、メッセージボックスの[OK]ボタンが押されるまで次の処理には進みません。
まとめ
今回はDLLの関数として引数のない、メッセージを表示する関数を新たに追加しました。
内容をまとめると下記の通りです。
引数がない関数は「関数名()」の括弧内には何も書かない(VBAと同じ)
戻り値がない関数の型は「void」にする
ほとんど前回やった内容と同じなので(メッセージを表示する処理が追加されただけ)、人によっては「前回と何が違うの?」と思われてもおかしくないような内容でした。
という訳で次回はもう少し実践で使えそうなVBA側から何らかの値を引数としてDLL側に渡すという処理を実装していきます。これができると、たとえばVBA側からファイルのパスを渡してそのパスを読み取ったDLL側でファイルに対して何らかの処理を行うことが可能になります。
(ちなみに目次の顔認識マクロも引数でVBAからDLLに画像パスを渡しているだけです)
【次回】DLL関数を作成する(引数あり)
【前回】空DLLファイルの作成と呼び出し
目次へ戻る