Add the current module path to the search path (#545)

Adding logic to add the current module path to the search path when attempting to load the depth engine.
This commit is contained in:
Derek M 2019-07-25 17:59:55 -07:00 коммит произвёл GitHub
Родитель 8774cc55b7
Коммит 98c8644f9e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 55 добавлений и 3 удалений

Просмотреть файл

@ -3,6 +3,8 @@
if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set(DYNLIB_SRCS dynlib_windows.c)
set(DYNLIB_DEPENDENCIES
pathcch.lib)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(DYNLIB_SRCS dynlib_linux.c)
else()
@ -18,7 +20,8 @@ target_include_directories(k4a_dynlib PUBLIC ${K4A_PRIV_INCLUDE_DIR})
target_link_libraries(k4a_dynlib PUBLIC
k4ainternal::allocator
k4ainternal::logging)
k4ainternal::logging
${DYNLIB_DEPENDENCIES})
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
target_link_libraries(k4a_dynlib PUBLIC dl)

Просмотреть файл

@ -10,6 +10,7 @@
// System dependencies
#include <windows.h>
#include <stdio.h>
#include <pathcch.h>
#define TOSTRING(x) STRINGIFY(x)
@ -37,6 +38,42 @@ static char *generate_file_name(const char *name, uint32_t major_ver, uint32_t m
return versioned_file_name;
}
static DLL_DIRECTORY_COOKIE add_current_module_to_search()
{
wchar_t path[MAX_PATH];
HMODULE hModule = NULL;
if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)add_current_module_to_search, &hModule) == 0)
{
LOG_WARNING("Failed to get current module (%d).", GetLastError());
return NULL;
}
if (GetModuleFileNameW(hModule, path, _countof(path)) == 0)
{
LOG_WARNING("Failed to get current module file name (%d).", GetLastError());
return NULL;
}
HRESULT result = PathCchRemoveFileSpec(path, _countof(path));
if (result != S_OK)
{
LOG_WARNING("Failed to remove the file name from the path (%d).", result);
return NULL;
}
// This adds the directory of the current module (k4a.dll) to the loader's path.
// The loader for C code only loads from the path of the current executable, not the current
// module. By adding the current module path, this will mimic how C# and Linux loads DLLs.
DLL_DIRECTORY_COOKIE dllDirectory = AddDllDirectory(path);
if (dllDirectory == 0)
{
LOG_WARNING("Failed to add the directory to the DLL search path (%d).", GetLastError());
}
return dllDirectory;
}
k4a_result_t dynlib_create(const char *name, uint32_t major_ver, uint32_t minor_ver, dynlib_t *dynlib_handle)
{
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, name == NULL);
@ -66,12 +103,16 @@ k4a_result_t dynlib_create(const char *name, uint32_t major_ver, uint32_t minor_
return K4A_RESULT_FAILED;
}
DLL_DIRECTORY_COOKIE dllDirectory = add_current_module_to_search();
dynlib_context_t *dynlib = dynlib_t_create(dynlib_handle);
k4a_result_t result = K4A_RESULT_FROM_BOOL(dynlib != NULL);
if (K4A_SUCCEEDED(result))
{
dynlib->handle = LoadLibraryA(versioned_name);
dynlib->handle = LoadLibraryExA(versioned_name,
NULL,
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);
result = (dynlib->handle != NULL) ? K4A_RESULT_SUCCEEDED : K4A_RESULT_FAILED;
if (K4A_FAILED(result))
@ -80,6 +121,14 @@ k4a_result_t dynlib_create(const char *name, uint32_t major_ver, uint32_t minor_
}
}
if (dllDirectory != NULL)
{
if (RemoveDllDirectory(dllDirectory) == 0)
{
LOG_WARNING("Failed to remove the directory from the DLL search path (%d).", GetLastError());
}
}
if (versioned_name != NULL)
{
free(versioned_name);
@ -132,4 +181,4 @@ void dynlib_destroy(dynlib_t dynlib_handle)
dynlib_t_destroy(dynlib_handle);
dynlib = NULL;
}
}