tools
読み取り中…
検索中…
一致する文字列を見つけられません
dll.h
[詳解]
1#ifdef BUILD
2 #define DLL extern "C" __declspec(dllexport)
3#else
4 // #define DLL __declspec(dllimport)
5 #pragma once
6 #include <windows.h>
7 #include <string>
8 #include <cstdint>
9 #include <stdexcept>
10
11/**
12 * @file dll.h
13 * @brief DLL 動的ロードユーティリティ
14 *
15 * - `BUILD` マクロが定義されている場合: `DLL` は `extern "C" __declspec(dllexport)` に展開されます。
16 * - 定義されていない場合: DLL から関数を遅延バインディングで呼び出す `DLL<R, Args...>` テンプレートクラスが提供されます。
17 */
18
19 /**
20 * @class DLL
21 * @brief DLL から関数を遅延バインディングで呼び出すファンクターテンプレートクラス
22 * @tparam R 関数の戻り値型
23 * @tparam Args 関数の引数型(パック)
24 *
25 * 初回呼び出し時に GetProcAddress で関数ポインタを解決し、その後はキャッシュした
26 * ポインタを使って呼び出します。
27 *
28 * @code
29 * HMODULE hMod = LoadLibrary("example.dll");
30 * DLL<int, const char*> myFunc(hMod, "MyFunction");
31 * int result = myFunc("hello");
32 * @endcode
33 */
34 template<typename R, typename... Args>
35 class DLL {
36 public:
37 /**
38 * @brief コンストラクタ
39 * @param hModule 関数を検索する DLL モジュールハンドル
40 * @param functionName 取得する関数名
41 */
42 DLL(HMODULE hModule, std::string functionName): func(nullptr), hModule(hModule) {functionName = functionName.c_str();}
43
44 /**
45 * @brief 関数を呼び出す(初回は GetProcAddress で解決)
46 * @param args 関数に渡す引数
47 * @return 関数の戻り値
48 * @throws std::runtime_error 関数が見つからない場合
49 */
50 R operator()(Args... args) {
51 if (!func) {
52 func = reinterpret_cast<R(*)(Args...)>(GetProcAddress(hModule, functionName));
53 if (!func) {
54 throw std::runtime_error("Failed to load function: " + std::string(functionName));
55 }
56 }
57 return func(std::forward<Args>(args)...);
58 }
59
60 private:
61 R(*func)(Args...); ///< 解決済み関数ポインタ
62 HMODULE hModule; ///< DLL モジュールハンドル
63 const char* functionName; ///< 関数名
64 };
65
66 /**
67 * @brief DLL モジュールを解放する
68 * @param dll 解放する HMODULE 変数への参照(解放後 nullptr にセットされる)
69 */
70 static void cleanDLL(HMODULE& dll) {
71 if (dll) {
72 FreeLibrary(dll);
73 dll = nullptr;
74 }
75 }
76#endif
DLL(HMODULE hModule, std::string functionName)
コンストラクタ
Definition dll.h:42
R operator()(Args... args)
関数を呼び出す(初回は GetProcAddress で解決)
Definition dll.h:50
static void cleanDLL(HMODULE &dll)
DLL モジュールを解放する
Definition dll.h:70