
LoadLibraryを必要とせず、DLLをメモリから直接ロードしてクリーンなプラグインインターフェースへ呼び出す、最小限のPEマッパー。
Windows x64 向けの、ホットスワップ可能なプラグインインターフェースを備えた最小限のリフレクティブ PE マッパー。メモリ上のバイトバッファから直接 DLL をマッピングし、そのエクスポートを解決し、LoadLibrary に触れることなくクリーンな IPlugin ABI を呼び出す。リフレクティブローダーとモジュール式プラグインアーキテクチャに関するブログ記事のコンパニオンコード。
完全な解説はこちら: Using Reflective Loaders to Replace LoadLibrary for Hot-Swappable Modules in C++
# Configure
cmake -B build
# Build
cmake --build build --config Release
# The build produces:
# build/Release/cmdplugin.dll (example plugin)
# build/Release/harness.exe (test harness)
# Map cmdplugin.dll from disk, run "dir C:\"
harness.exe cmdplugin.dll "dir C:\"
# Default: loads cmdplugin.dll, runs "whoami"
harness.exe
ハーネスは DLL をバイトバッファに読み込み、リフレクティブローダーでマッピングし、プラグインのエクスポートを解決し、IPlugin インターフェースを通じてコマンドをディスパッチする。
ReflectivePluginLoader/
├── CMakeLists.txt # Root build
├── Include/
│ ├── IPlugin.h # Plugin ABI (TaskApi, IPlugin, helpers)
│ └── ReflectiveLoaderEngine.h # PE mapper + export resolver
├── Modules/
│ └── CmdPlugin/
│ ├── cmdplugin.cpp # Example: command execution plugin
│ └── CMakeLists.txt
├── Testing/
│ ├── main.cpp # Test harness (loads DLL from file)
│ └── CMakeLists.txt
└── Tools/
└── file2hex.py # Convert a DLL to a C byte array
Modules/ の下に新しいディレクトリを作成する。IPlugin.h をインクルードし、IPlugin インターフェースを実装する:#include "IPlugin.h"
class MyPlugin : public IPlugin {
public:
void init() const override { /* setup */ }
void execute(TaskApi* task) const override { /* do work */ }
void cleanup() const override { /* teardown */ }
};
5 つのエクスポート関数 (create_plugin、destroy_plugin、plugin_init、plugin_exec、plugin_cleanup) を、CRT セーフなクロスモジュール割り当てのために HeapAlloc/placement new を使って実装する。
CMakeLists.txt を追加し、ルートの CMakeLists.txt に add_subdirectory() で登録する。
ホストはモジュールが内部で何をするかを知る必要はない。マッピングし、解決し、init -> execute -> cleanup を呼び出して、次へ進む。
マッパーは基本機能を処理し、意図的にそこで止まっている:
モジュールがこれらのいずれかを必要とする場合は、マッパーを拡張するか、明確なエラーで早期にモジュールを拒否すること。中途半端な暗黙のサポートは最悪の障害モードである。