
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 */ }
};
CRT 안전한 크로스 모듈 할당을 위해 HeapAlloc/placement new를 사용하여 다섯 개의 익스포트 함수(create_plugin, destroy_plugin, plugin_init, plugin_exec, plugin_cleanup)를 구현합니다.
CMakeLists.txt를 추가하고 루트 CMakeLists.txt에 add_subdirectory()로 등록합니다.
호스트는 모듈이 내부적으로 무엇을 하는지 알 필요가 없습니다. 매핑하고, 해석하고, init -> execute -> cleanup을 호출한 뒤 다음으로 넘어갑니다.
매퍼는 기본적인 것들을 처리하며 의도적으로 거기서 멈춥니다:
모듈이 이 중 하나라도 필요로 한다면, 매퍼를 확장하거나 명확한 오류와 함께 모듈을 조기에 거부하십시오. 조용한 반쪽 지원이 최악의 실패 모드입니다.