Moved SO Loader to util library (#8017)

* Moved SO Loader to util library

* Removed redundant headers

* Fixed code style

* Fixed build

* Fixed templateFuncTests

* Removed SharedObjectLoader from util library
This commit is contained in:
Ilya Churaev 2021-10-21 06:47:48 +03:00 committed by GitHub
parent 0f3c10c810
commit 83fe59bd3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 207 additions and 203 deletions

View File

@ -45,9 +45,6 @@ if (LINUX)
file (GLOB LIBRARY_HEADERS file (GLOB LIBRARY_HEADERS
${LIBRARY_HEADERS} ${LIBRARY_HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/src/os/lin/*.hpp) ${CMAKE_CURRENT_SOURCE_DIR}/src/os/lin/*.hpp)
elseif (UNIX)
list (APPEND LIBRARY_SRC
${CMAKE_CURRENT_SOURCE_DIR}/src/os/lin/lin_shared_object_loader.cpp)
endif() endif()
if (WIN32) if (WIN32)

View File

@ -64,8 +64,15 @@ public:
* @param name Name of a shared library file * @param name Name of a shared library file
*/ */
template <typename C, typename = enableIfSupportedChar<C>> template <typename C, typename = enableIfSupportedChar<C>>
SOPointer(const std::basic_string<C>& name) : _so(name.c_str()) { SOPointer(const std::basic_string<C>& name) {
Load(std::integral_constant<bool, HasRelease::value>{}); try {
_so = SharedObjectLoader(name.c_str());
Load(std::integral_constant<bool, HasRelease::value>{});
} catch (const std::runtime_error& ex) {
IE_THROW() << ex.what();
} catch (...) {
details::Rethrow();
}
} }
/** /**
@ -158,6 +165,8 @@ protected:
using CreateF = void(std::shared_ptr<T>&); using CreateF = void(std::shared_ptr<T>&);
reinterpret_cast<CreateF*>(create)(_ptr); reinterpret_cast<CreateF*>(create)(_ptr);
} }
} catch (const std::runtime_error& ex) {
IE_THROW() << ex.what();
} catch (...) { } catch (...) {
details::Rethrow(); details::Rethrow();
} }
@ -170,6 +179,8 @@ protected:
try { try {
using CreateF = void(std::shared_ptr<T>&); using CreateF = void(std::shared_ptr<T>&);
reinterpret_cast<CreateF*>(_so.get_symbol(SOCreatorTrait<T>::name))(_ptr); reinterpret_cast<CreateF*>(_so.get_symbol(SOCreatorTrait<T>::name))(_ptr);
} catch (const std::runtime_error& ex) {
IE_THROW() << ex.what();
} catch (...) { } catch (...) {
details::Rethrow(); details::Rethrow();
} }

View File

@ -37,6 +37,7 @@
#include "openvino/runtime/core.hpp" #include "openvino/runtime/core.hpp"
#include "openvino/runtime/executable_network.hpp" #include "openvino/runtime/executable_network.hpp"
#include "openvino/util/file_util.hpp" #include "openvino/util/file_util.hpp"
#include "openvino/util/shared_object.hpp"
#include "xml_parse_utils.h" #include "xml_parse_utils.h"
using namespace InferenceEngine::PluginConfigParams; using namespace InferenceEngine::PluginConfigParams;
@ -685,6 +686,8 @@ public:
// plugin is not created by e.g. invalid env // plugin is not created by e.g. invalid env
} catch (ov::Exception&) { } catch (ov::Exception&) {
// plugin is not created by e.g. invalid env // plugin is not created by e.g. invalid env
} catch (std::runtime_error&) {
// plugin is not created by e.g. invalid env
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
IE_THROW() << "An exception is thrown while trying to create the " << deviceName IE_THROW() << "An exception is thrown while trying to create the " << deviceName
<< " device and call GetMetric: " << ex.what(); << " device and call GetMetric: " << ex.what();
@ -724,11 +727,11 @@ public:
auto it_plugin = plugins.find(deviceName); auto it_plugin = plugins.find(deviceName);
if (it_plugin == plugins.end()) { if (it_plugin == plugins.end()) {
PluginDescriptor desc = it->second; PluginDescriptor desc = it->second;
auto so = load_shared_object(desc.libraryLocation.c_str()); auto so = ov::util::load_shared_object(desc.libraryLocation.c_str());
try { try {
using CreateF = void(std::shared_ptr<ie::IInferencePlugin>&); using CreateF = void(std::shared_ptr<ie::IInferencePlugin>&);
std::shared_ptr<ie::IInferencePlugin> plugin_impl; std::shared_ptr<ie::IInferencePlugin> plugin_impl;
reinterpret_cast<CreateF*>(get_symbol(so, OV_PP_TOSTRING(IE_CREATE_PLUGIN)))(plugin_impl); reinterpret_cast<CreateF*>(ov::util::get_symbol(so, OV_PP_TOSTRING(IE_CREATE_PLUGIN)))(plugin_impl);
auto plugin = InferencePlugin{so, plugin_impl}; auto plugin = InferencePlugin{so, plugin_impl};
{ {

View File

@ -1,97 +0,0 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <dlfcn.h>
#include <iostream>
#include "details/ie_so_loader.h"
#include "file_utils.h"
#include "openvino/util/file_util.hpp"
#include "shared_object.hpp"
namespace ov {
namespace runtime {
std::shared_ptr<void> load_shared_object(const char* path) {
auto shared_object = std::shared_ptr<void>{dlopen(path, RTLD_NOW), [](void* shared_object) {
if (shared_object != nullptr) {
if (0 != dlclose(shared_object)) {
std::cerr << "dlclose failed: " << dlerror() << std::endl;
}
}
}};
if (!shared_object) {
IE_THROW() << "Cannot load library '" << path << "': " << dlerror();
}
return shared_object;
}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
std::shared_ptr<void> load_shared_object(const wchar_t* path) {
return load_shared_object(ov::util::wstring_to_string(path).c_str());
}
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
void* get_symbol(const std::shared_ptr<void>& shared_object, const char* symbol_name) {
if (!shared_object) {
IE_THROW() << "Cannot get '" << symbol_name << "' content from unknown library!";
}
void* procAddr = nullptr;
procAddr = dlsym(shared_object.get(), symbol_name);
if (procAddr == nullptr) {
IE_THROW(NotFound) << "dlSym cannot locate method '" << symbol_name << "': " << dlerror();
}
return procAddr;
}
} // namespace runtime
} // namespace ov
namespace InferenceEngine {
namespace details {
struct SharedObjectLoader::Impl {
std::shared_ptr<void> shared_object = nullptr;
explicit Impl(const std::shared_ptr<void>& shared_object_) : shared_object{shared_object_} {}
explicit Impl(const char* pluginName) : shared_object{ov::runtime::load_shared_object(pluginName)} {}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
explicit Impl(const wchar_t* pluginName) : Impl(ov::util::wstring_to_string(pluginName).c_str()) {}
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
void* get_symbol(const char* symbolName) const {
return ov::runtime::get_symbol(shared_object, symbolName);
}
};
SharedObjectLoader::SharedObjectLoader(const std::shared_ptr<void>& shared_object) {
_impl.reset(new Impl(shared_object));
}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
SharedObjectLoader::SharedObjectLoader(const wchar_t* pluginName) {
_impl.reset(new Impl(pluginName));
}
#endif
SharedObjectLoader::SharedObjectLoader(const char* pluginName) {
_impl.reset(new Impl(pluginName));
}
SharedObjectLoader::~SharedObjectLoader() {}
void* SharedObjectLoader::get_symbol(const char* symbolName) const {
if (_impl == nullptr) {
IE_THROW(NotAllocated) << "SharedObjectLoader is not initialized";
}
return _impl->get_symbol(symbolName);
}
std::shared_ptr<void> SharedObjectLoader::get() const {
return _impl->shared_object;
}
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,57 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "details/ie_so_loader.h"
#include "ie_common.h"
#include "openvino/util/file_util.hpp"
#include "openvino/util/shared_object.hpp"
namespace InferenceEngine {
namespace details {
struct SharedObjectLoader::Impl {
std::shared_ptr<void> shared_object = nullptr;
explicit Impl(const std::shared_ptr<void>& shared_object_) : shared_object{shared_object_} {}
explicit Impl(const char* pluginName) : shared_object{ov::util::load_shared_object(pluginName)} {}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
explicit Impl(const wchar_t* pluginName) : Impl(ov::util::wstring_to_string(pluginName).c_str()) {}
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
void* get_symbol(const char* symbolName) const {
return ov::util::get_symbol(shared_object, symbolName);
}
};
SharedObjectLoader::SharedObjectLoader(const std::shared_ptr<void>& shared_object) {
_impl.reset(new Impl(shared_object));
}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
SharedObjectLoader::SharedObjectLoader(const wchar_t* pluginName) {
_impl.reset(new Impl(pluginName));
}
#endif
SharedObjectLoader::SharedObjectLoader(const char* pluginName) {
_impl.reset(new Impl(pluginName));
}
SharedObjectLoader::~SharedObjectLoader() {}
void* SharedObjectLoader::get_symbol(const char* symbolName) const {
if (_impl == nullptr) {
IE_THROW(NotAllocated) << "SharedObjectLoader is not initialized";
}
return _impl->get_symbol(symbolName);
}
std::shared_ptr<void> SharedObjectLoader::get() const {
return _impl->shared_object;
}
} // namespace details
} // namespace InferenceEngine

View File

@ -15,7 +15,6 @@
#include <type_traits> #include <type_traits>
#include "openvino/runtime/common.hpp" #include "openvino/runtime/common.hpp"
#include "shared_object.hpp"
namespace ov { namespace ov {
namespace runtime { namespace runtime {

View File

@ -5,7 +5,7 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <file_utils.h> #include <file_utils.h>
#include "shared_object.hpp" #include "openvino/util/shared_object.hpp"
#include <cpp/ie_plugin.hpp> #include <cpp/ie_plugin.hpp>
using namespace ::testing; using namespace ::testing;
@ -19,14 +19,14 @@ protected:
} }
void loadDll(const string &libraryName) { void loadDll(const string &libraryName) {
shared_object = ov::runtime::load_shared_object(libraryName.c_str()); shared_object = ov::util::load_shared_object(libraryName.c_str());
} }
std::shared_ptr<void> shared_object; std::shared_ptr<void> shared_object;
using CreateF = void(std::shared_ptr<InferenceEngine::IInferencePlugin>&); using CreateF = void(std::shared_ptr<InferenceEngine::IInferencePlugin>&);
std::function<CreateF> make_std_function(const std::string& functionName) { std::function<CreateF> make_std_function(const std::string& functionName) {
std::function<CreateF> ptr(reinterpret_cast<CreateF*>(ov::runtime::get_symbol(shared_object, functionName.c_str()))); std::function<CreateF> ptr(reinterpret_cast<CreateF*>(ov::util::get_symbol(shared_object, functionName.c_str())));
return ptr; return ptr;
} }
}; };
@ -37,7 +37,7 @@ TEST_F(SharedObjectOVTests, canLoadExistedPlugin) {
} }
TEST_F(SharedObjectOVTests, loaderThrowsIfNoPlugin) { TEST_F(SharedObjectOVTests, loaderThrowsIfNoPlugin) {
EXPECT_THROW(loadDll("wrong_name"), InferenceEngine::Exception); EXPECT_THROW(loadDll("wrong_name"), std::runtime_error);
} }
TEST_F(SharedObjectOVTests, canFindExistedMethod) { TEST_F(SharedObjectOVTests, canFindExistedMethod) {
@ -49,7 +49,7 @@ TEST_F(SharedObjectOVTests, canFindExistedMethod) {
TEST_F(SharedObjectOVTests, throwIfMethodNofFoundInLibrary) { TEST_F(SharedObjectOVTests, throwIfMethodNofFoundInLibrary) {
loadDll(get_mock_engine_name()); loadDll(get_mock_engine_name());
EXPECT_THROW(make_std_function("wrong_function"), InferenceEngine::Exception); EXPECT_THROW(make_std_function("wrong_function"), std::runtime_error);
} }
TEST_F(SharedObjectOVTests, canCallExistedMethod) { TEST_F(SharedObjectOVTests, canCallExistedMethod) {

View File

@ -41,7 +41,7 @@ TEST_F(SharedObjectLoaderTests, canLoadExistedPlugin) {
} }
TEST_F(SharedObjectLoaderTests, loaderThrowsIfNoPlugin) { TEST_F(SharedObjectLoaderTests, loaderThrowsIfNoPlugin) {
EXPECT_THROW(loadDll("wrong_name"), InferenceEngine::Exception); EXPECT_THROW(loadDll("wrong_name"), std::runtime_error);
} }
TEST_F(SharedObjectLoaderTests, canFindExistedMethod) { TEST_F(SharedObjectLoaderTests, canFindExistedMethod) {
@ -53,7 +53,7 @@ TEST_F(SharedObjectLoaderTests, canFindExistedMethod) {
TEST_F(SharedObjectLoaderTests, throwIfMethodNofFoundInLibrary) { TEST_F(SharedObjectLoaderTests, throwIfMethodNofFoundInLibrary) {
loadDll(get_mock_engine_name()); loadDll(get_mock_engine_name());
EXPECT_THROW(make_std_function("wrong_function"), InferenceEngine::Exception); EXPECT_THROW(make_std_function("wrong_function"), std::runtime_error);
} }
TEST_F(SharedObjectLoaderTests, canCallExistedMethod) { TEST_F(SharedObjectLoaderTests, canCallExistedMethod) {

View File

@ -9,6 +9,18 @@ file(GLOB_RECURSE PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp)
set(UTIL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/) set(UTIL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/)
if (WIN32)
# Remove linux specific files
file(GLOB_RECURSE LIN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/os/lin/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/os/lin/*.hpp)
list(REMOVE_ITEM LIBRARY_SRC ${LIN_FILES})
else()
# Remove windows specific files
file(GLOB_RECURSE WIN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/os/win/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/os/win/*.hpp)
list(REMOVE_ITEM LIBRARY_SRC ${WIN_FILES})
endif()
# Create named folders for the sources within the .vcproj # Create named folders for the sources within the .vcproj
# Empty name lists them directly under the .vcproj # Empty name lists them directly under the .vcproj

View File

@ -9,15 +9,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#ifndef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT #include "openvino/util/util.hpp"
# ifdef _WIN32
# if defined __INTEL_COMPILER || defined _MSC_VER
# define OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# endif
# elif defined(__GNUC__) && (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 2)) || defined(__clang__)
# define OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# endif
#endif
namespace ov { namespace ov {
namespace util { namespace util {

View File

@ -4,21 +4,24 @@
/** /**
* @brief A header file for definition of abstraction over platform specific shared objects * @brief A header file for definition of abstraction over platform specific shared objects
* @file ie_system_conf.h * @file shared_object.hpp
*/ */
#pragma once #pragma once
#include "ie_api.h" #include <memory>
#include "openvino/util/util.hpp"
namespace ov { namespace ov {
namespace runtime { namespace util {
/** /**
* @brief Loads a library with the name specified. * @brief Loads a library with the name specified.
* @param path Full or relative path to the plugin library * @param path Full or relative path to the plugin library
* @return Reference to shared object * @return Reference to shared object
*/ */
INFERENCE_ENGINE_API_CPP(std::shared_ptr<void>) load_shared_object(const char* path); std::shared_ptr<void> load_shared_object(const char* path);
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT #ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
/** /**
@ -26,7 +29,7 @@ INFERENCE_ENGINE_API_CPP(std::shared_ptr<void>) load_shared_object(const char* p
* @param path Full or relative path to the plugin library * @param path Full or relative path to the plugin library
* @return Reference to shared object * @return Reference to shared object
*/ */
INFERENCE_ENGINE_API_CPP(std::shared_ptr<void>) load_shared_object(const wchar_t* path); std::shared_ptr<void> load_shared_object(const wchar_t* path);
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT #endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
/** /**
* @brief Searches for a function symbol in the loaded module * @brief Searches for a function symbol in the loaded module
@ -35,6 +38,7 @@ INFERENCE_ENGINE_API_CPP(std::shared_ptr<void>) load_shared_object(const wchar_t
* @return A pointer to the function if found * @return A pointer to the function if found
* @throws Exception if the function is not found * @throws Exception if the function is not found
*/ */
INFERENCE_ENGINE_API_CPP(void*) get_symbol(const std::shared_ptr<void>& shared_object, const char* symbolName); void* get_symbol(const std::shared_ptr<void>& shared_object, const char* symbolName);
} // namespace runtime
} // namespace util
} // namespace ov } // namespace ov

View File

@ -0,0 +1,15 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#ifndef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# ifdef _WIN32
# if defined __INTEL_COMPILER || defined _MSC_VER
# define OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# endif
# elif defined(__GNUC__) && (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 2)) || defined(__clang__)
# define OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# endif
#endif

View File

@ -0,0 +1,53 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <dlfcn.h>
#include <iostream>
#include <sstream>
#include "openvino/util/file_util.hpp"
#include "openvino/util/shared_object.hpp"
namespace ov {
namespace util {
std::shared_ptr<void> load_shared_object(const char* path) {
auto shared_object = std::shared_ptr<void>{dlopen(path, RTLD_NOW), [](void* shared_object) {
if (shared_object != nullptr) {
if (0 != dlclose(shared_object)) {
std::cerr << "dlclose failed: " << dlerror() << std::endl;
}
}
}};
if (!shared_object) {
std::stringstream ss;
ss << "Cannot load library '" << path << "': " << dlerror();
throw std::runtime_error(ss.str());
}
return shared_object;
}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
std::shared_ptr<void> load_shared_object(const wchar_t* path) {
return load_shared_object(ov::util::wstring_to_string(path).c_str());
}
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
void* get_symbol(const std::shared_ptr<void>& shared_object, const char* symbol_name) {
if (!shared_object) {
std::stringstream ss;
ss << "Cannot get '" << symbol_name << "' content from unknown library!";
throw std::runtime_error(ss.str());
}
void* procAddr = nullptr;
procAddr = dlsym(shared_object.get(), symbol_name);
if (procAddr == nullptr) {
std::stringstream ss;
ss << "dlSym cannot locate method '" << symbol_name << "': " << dlerror();
throw std::runtime_error(ss.str());
}
return procAddr;
}
} // namespace util
} // namespace ov

View File

@ -2,10 +2,10 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
#include "ie_common.h" #include <sstream>
#include "details/ie_so_loader.h"
#include "file_utils.h" #include "openvino/util/file_util.hpp"
#include "shared_object.hpp" #include "openvino/util/shared_object.hpp"
// //
// LoadLibraryA, LoadLibraryW: // LoadLibraryA, LoadLibraryW:
@ -58,23 +58,24 @@
// //
#if defined(WINAPI_FAMILY) && !WINAPI_PARTITION_DESKTOP #if defined(WINAPI_FAMILY) && !WINAPI_PARTITION_DESKTOP
# error "Only WINAPI_PARTITION_DESKTOP is supported, because of LoadLibrary[A|W]" # error "Only WINAPI_PARTITION_DESKTOP is supported, because of LoadLibrary[A|W]"
#endif #endif
#include <mutex>
#include <direct.h> #include <direct.h>
#include <mutex>
#ifndef NOMINMAX #ifndef NOMINMAX
# define NOMINMAX # define NOMINMAX
#endif #endif
#include <windows.h> #include <windows.h>
namespace ov { namespace ov {
namespace runtime { namespace util {
std::shared_ptr<void> load_shared_object(const char* path) { std::shared_ptr<void> load_shared_object(const char* path) {
void* shared_object = nullptr; void* shared_object = nullptr;
using GetDllDirectoryA_Fnc = DWORD(*)(DWORD, LPSTR); using GetDllDirectoryA_Fnc = DWORD (*)(DWORD, LPSTR);
GetDllDirectoryA_Fnc IEGetDllDirectoryA = nullptr; GetDllDirectoryA_Fnc IEGetDllDirectoryA = nullptr;
if (HMODULE hm = GetModuleHandleW(L"kernel32.dll")) { if (HMODULE hm = GetModuleHandleW(L"kernel32.dll")) {
IEGetDllDirectoryA = reinterpret_cast<GetDllDirectoryA_Fnc>(GetProcAddress(hm, "GetDllDirectoryA")); IEGetDllDirectoryA = reinterpret_cast<GetDllDirectoryA_Fnc>(GetProcAddress(hm, "GetDllDirectoryA"));
@ -99,7 +100,7 @@ std::shared_ptr<void> load_shared_object(const char* path) {
std::string original(path); std::string original(path);
original[pos - path] = 0; original[pos - path] = 0;
return original; return original;
} (); }();
SetDllDirectoryA(dirname.c_str()); SetDllDirectoryA(dirname.c_str());
shared_object = LoadLibraryA(path); shared_object = LoadLibraryA(path);
@ -113,11 +114,11 @@ std::shared_ptr<void> load_shared_object(const char* path) {
if (!shared_object) { if (!shared_object) {
char cwd[1024]; char cwd[1024];
IE_THROW() << "Cannot load library '" << path << "': " << GetLastError() std::stringstream ss;
<< " from cwd: " << _getcwd(cwd, sizeof(cwd)); ss << "Cannot load library '" << path << "': " << GetLastError() << " from cwd: " << _getcwd(cwd, sizeof(cwd));
throw std::runtime_error(ss.str());
} }
return {shared_object, return {shared_object, [](void* shared_object) {
[] (void* shared_object) {
FreeLibrary(reinterpret_cast<HMODULE>(shared_object)); FreeLibrary(reinterpret_cast<HMODULE>(shared_object));
}}; }};
} }
@ -125,13 +126,13 @@ std::shared_ptr<void> load_shared_object(const char* path) {
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT #ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
std::shared_ptr<void> load_shared_object(const wchar_t* path) { std::shared_ptr<void> load_shared_object(const wchar_t* path) {
void* shared_object = nullptr; void* shared_object = nullptr;
using GetDllDirectoryW_Fnc = DWORD(*)(DWORD, LPWSTR); using GetDllDirectoryW_Fnc = DWORD (*)(DWORD, LPWSTR);
static GetDllDirectoryW_Fnc IEGetDllDirectoryW = nullptr; static GetDllDirectoryW_Fnc IEGetDllDirectoryW = nullptr;
if (HMODULE hm = GetModuleHandleW(L"kernel32.dll")) { if (HMODULE hm = GetModuleHandleW(L"kernel32.dll")) {
IEGetDllDirectoryW = reinterpret_cast<GetDllDirectoryW_Fnc>(GetProcAddress(hm, "GetDllDirectoryW")); IEGetDllDirectoryW = reinterpret_cast<GetDllDirectoryW_Fnc>(GetProcAddress(hm, "GetDllDirectoryW"));
} }
// ExcludeCurrentDirectory // ExcludeCurrentDirectory
#if !WINAPI_PARTITION_SYSTEM # if !WINAPI_PARTITION_SYSTEM
if (IEGetDllDirectoryW && IEGetDllDirectoryW(0, NULL) <= 1) { if (IEGetDllDirectoryW && IEGetDllDirectoryW(0, NULL) <= 1) {
SetDllDirectoryW(L""); SetDllDirectoryW(L"");
} }
@ -147,23 +148,24 @@ std::shared_ptr<void> load_shared_object(const wchar_t* path) {
std::wstring original(path); std::wstring original(path);
original[pos - path] = 0; original[pos - path] = 0;
return original; return original;
} (); }();
SetDllDirectoryW(dirname.c_str()); SetDllDirectoryW(dirname.c_str());
shared_object = LoadLibraryW(path); shared_object = LoadLibraryW(path);
SetDllDirectoryW(&lpBuffer.front()); SetDllDirectoryW(&lpBuffer.front());
} }
#endif # endif
if (!shared_object) { if (!shared_object) {
shared_object = LoadLibraryW(path); shared_object = LoadLibraryW(path);
} }
if (!shared_object) { if (!shared_object) {
char cwd[1024]; char cwd[1024];
IE_THROW() << "Cannot load library '" << ov::util::wstring_to_string(std::wstring(path)) << "': " << GetLastError() std::stringstream ss;
<< " from cwd: " << _getcwd(cwd, sizeof(cwd)); ss << "Cannot load library '" << ov::util::wstring_to_string(std::wstring(path)) << "': " << GetLastError()
<< " from cwd: " << _getcwd(cwd, sizeof(cwd));
throw std::runtime_error(ss.str());
} }
return {shared_object, return {shared_object, [](void* shared_object) {
[] (void* shared_object) {
FreeLibrary(reinterpret_cast<HMODULE>(shared_object)); FreeLibrary(reinterpret_cast<HMODULE>(shared_object));
}}; }};
} }
@ -171,62 +173,18 @@ std::shared_ptr<void> load_shared_object(const wchar_t* path) {
void* get_symbol(const std::shared_ptr<void>& shared_object, const char* symbol_name) { void* get_symbol(const std::shared_ptr<void>& shared_object, const char* symbol_name) {
if (!shared_object) { if (!shared_object) {
IE_THROW() << "Cannot get '" << symbol_name << "' content from unknown library!"; std::stringstream ss;
ss << "Cannot get '" << symbol_name << "' content from unknown library!";
throw std::runtime_error(ss.str());
} }
auto procAddr = reinterpret_cast<void*>(GetProcAddress( auto procAddr = reinterpret_cast<void*>(
reinterpret_cast<HMODULE>(const_cast<void*>(shared_object.get())), symbol_name)); GetProcAddress(reinterpret_cast<HMODULE>(const_cast<void*>(shared_object.get())), symbol_name));
if (procAddr == nullptr) { if (procAddr == nullptr) {
IE_THROW(NotFound) std::stringstream ss;
<< "GetProcAddress cannot locate method '" << symbol_name << "': " << GetLastError(); ss << "GetProcAddress cannot locate method '" << symbol_name << "': " << GetLastError();
throw std::runtime_error(ss.str());
} }
return procAddr; return procAddr;
} }
} // namespace runtime } // namespace util
} // namespace ov } // namespace ov
namespace InferenceEngine {
namespace details {
struct SharedObjectLoader::Impl {
std::shared_ptr<void> shared_object = nullptr;
explicit Impl(const std::shared_ptr<void>& shared_object_) : shared_object{shared_object_} {}
explicit Impl(const char* pluginName) : shared_object{ov::runtime::load_shared_object(pluginName)} {}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
explicit Impl(const wchar_t* pluginName) : shared_object{ov::runtime::load_shared_object(pluginName)} {}
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
void* get_symbol(const char* symbolName) const {
return ov::runtime::get_symbol(shared_object, symbolName);
}
};
SharedObjectLoader::SharedObjectLoader(const std::shared_ptr<void>& shared_object) {
_impl.reset(new Impl(shared_object));
}
SharedObjectLoader::~SharedObjectLoader() {}
SharedObjectLoader::SharedObjectLoader(const char * pluginName) {
_impl = std::make_shared<Impl>(pluginName);
}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
SharedObjectLoader::SharedObjectLoader(const wchar_t* pluginName) {
_impl = std::make_shared<Impl>(pluginName);
}
#endif
void* SharedObjectLoader::get_symbol(const char* symbolName) const {
if (_impl == nullptr) {
IE_THROW(NotAllocated) << "SharedObjectLoader is not initialized";
}
return _impl->get_symbol(symbolName);
}
std::shared_ptr<void> SharedObjectLoader::get() const {
return _impl->shared_object;
}
} // namespace details
} // namespace InferenceEngine