Skip to content

Instantly share code, notes, and snippets.

@mrdooz
Created February 18, 2018 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrdooz/c5c7458ba7edb772d659b5a1c0ed379b to your computer and use it in GitHub Desktop.
Save mrdooz/c5c7458ba7edb772d659b5a1c0ed379b to your computer and use it in GitHub Desktop.
dynamic dll reloading
//------------------------------------------------------------------------------
static error_code load_editor_dll()
{
char path[MAX_PATH];
GetModuleFileNameA(NULL, path, MAX_PATH);
char* last_slash = strrchr(path, '\\');
if (!last_slash)
return make_error_code(error::error_finding_editor_dll);
strcpy(last_slash, "\\editor.dll");
if (!file_exists(path))
{
return make_error_code(error::error_finding_editor_dll);
}
// check if the version of the dll is newer than what we have loaded
time_t t = last_modification(path);
if (t > _last_mod_time)
{
// copy the dll to a tmp file
string dest = get_temp_filename();
CopyFileA(path, dest.c_str(), FALSE);
// try to load dll and get procs before closing the existing dll
u32 old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
HMODULE tmp_module = LoadLibrary(dest.c_str());
SetErrorMode(old_error_mode);
if (!tmp_module)
return make_error_code(error::error_loading_editor_dll);
fn_editor_init tmp_init = (fn_editor_init)GetProcAddress(tmp_module, "init");
if (!tmp_init)
{
LOG_WARNING("Unable to find 'init' in editor dll");
return make_error_code(error::error_loading_editor_dll);
}
fn_editor_close tmp_close = (fn_editor_close)GetProcAddress(tmp_module, "close");
if (!tmp_close)
{
LOG_WARNING("Unable to find 'close' in editor dll");
return make_error_code(error::error_loading_editor_dll);
}
// looks good, so close existing module and do the swap
if (_editor_module)
{
g_editor_state->save(_json_state);
save_file(_state_path.c_str(), _json_state.dump(4));
_editor_close();
FreeLibrary(_editor_module);
}
_editor_module = tmp_module;
_editor_init = tmp_init;
_editor_close = tmp_close;
if (!_editor_init(g_engine_state, &g_editor_state))
return make_error_code(error::error_initializing_editor);
g_editor_state->load(_json_state);
_last_mod_time = t;
// delete any old temp files
for (const string& str : _tempfiles)
{
DeleteFileA(str.c_str());
}
_tempfiles.clear();
_tempfiles.insert(dest);
}
return error_code();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment