From 9f4f26ac94b5134030d863a2c0f27ef245b95ef9 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 29 Aug 2024 10:33:08 -0700 Subject: [PATCH 1/9] lazy load --- src/bb/image-io/rt_u3v.h | 7 +--- src/dynamic_module.h | 83 ++++++++++++++++++++++++++++++++-------- 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/src/bb/image-io/rt_u3v.h b/src/bb/image-io/rt_u3v.h index b44cc462..9ef8ce57 100644 --- a/src/bb/image-io/rt_u3v.h +++ b/src/bb/image-io/rt_u3v.h @@ -4,7 +4,7 @@ #include #include #include - +#include #include #include "log.h" @@ -328,7 +328,7 @@ class U3V { protected: U3V(int32_t num_sensor, bool frame_sync, bool realtime_display_mode, bool sim_mode, int32_t width, int32_t height , float_t fps, const std::string & pixel_format, char* dev_id = nullptr) - : gobject_(GOBJECT_FILE, true), aravis_(ARAVIS_FILE, true), + : gobject_(GOBJECT_FILE, true), aravis_(ARAVIS_FILE, true, true), num_sensor_(num_sensor), frame_count_method_(FrameCountMethod::UNAVAILABLE), frame_sync_(frame_sync), realtime_display_mode_(realtime_display_mode), is_gendc_(false), is_param_integer_(false), devices_(num_sensor), buffers_(num_sensor), operation_mode_(OperationMode::Came1USB1), frame_cnt_(0), device_idx_(-1), disposed_(false), sim_mode_(sim_mode) @@ -357,9 +357,6 @@ class U3V { } void init_symbols_aravis() { - if (!aravis_.is_available()) { - throw ::std::runtime_error("libaravis-0.8 is unavailable on your system."); - } #define GET_SYMBOL(LOCAL_VAR, TARGET_SYMBOL) \ LOCAL_VAR = aravis_.get_symbol(TARGET_SYMBOL); \ diff --git a/src/dynamic_module.h b/src/dynamic_module.h index 92092bc9..3fccad5c 100644 --- a/src/dynamic_module.h +++ b/src/dynamic_module.h @@ -6,6 +6,7 @@ #if _WIN32 #define WIN32_LEAN_AND_MEAN #include +#include #define ION_DYNAMIC_MODULE_PREFIX "" #define ION_DYNAMIC_MODULE_EXT ".dll" #elif __APPLE__ @@ -37,12 +38,13 @@ class DynamicModule { using Handle = void*; #endif - DynamicModule(const std::string& module_name_or_path, bool essential = true) { + DynamicModule(const std::string& module_name_or_path, bool essential = true, bool lazy_load = false) { if (module_name_or_path == "") { - handle_ = nullptr; - return; + handle_ = nullptr; + return; } + // set target std::string target; if (std::filesystem::exists(module_name_or_path) || has_prefix_and_ext(module_name_or_path)) { // This is absolute path or file name @@ -50,18 +52,29 @@ class DynamicModule { } else { target = std::string(ION_DYNAMIC_MODULE_PREFIX) + module_name_or_path + std::string(ION_DYNAMIC_MODULE_EXT); } + target_ = target; + essential_ = essential; + + if (lazy_load){ +#ifdef _WIN32 + handle_ = nullptr; +#else + handle_ = RTLD_DEFAULT; +#endif + }else{ // TODO: WIP: test moduel_name_or_path using std::filesystem #ifdef _WIN32 - handle_ = LoadLibraryA(target.c_str()); + handle_ = LoadLibraryA(target.c_str()); #else - handle_ = dlopen(target.c_str(), RTLD_NOW); + handle_ = dlopen(target.c_str(), RTLD_NOW); #endif - if (handle_ == nullptr) { - if (essential) { - throw std::runtime_error(getErrorString()); - } else { - log::warn("Not found inessential library {} : {}", target, getErrorString()); + if (handle_ == nullptr) { + if (essential) { + throw std::runtime_error(getErrorString()); + } else { + log::warn("Not found inessential library {} : {}", target, getErrorString()); + } } } } @@ -74,15 +87,53 @@ class DynamicModule { } bool is_available(void) const { - return handle_ != NULL; + return handle_ != nullptr; } template - T get_symbol(const std::string &symbol_name) const { -#if defined(_WIN32) - return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); + T get_symbol(const std::string &symbol_name) { +#ifdef _WIN32 + if (handle_ != nullptr){ + return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); + }else{ + Handle hmods[1024]; + DWORD cb_needed; + if (EnumProcessModules(GetCurrentProcess(), hmods, sizeof(hmods), &cb_needed)) { + for (unsigned int i = 0; i < (cb_needed / sizeof(HMODULE)); i++) { + char path[MAX_PATH]; + // Get the module name + if (GetModuleFileNameA(hmods[i], path, sizeof(path) / sizeof(char))) { + // Try to get the address of the symbol in this module + FARPROC func_ptr = GetProcAddress(hmods[i], symbol_name.c_str()); + if (func_ptr != nullptr) { + handle_ = hmods[i]; + return reinterpret_cast(func_ptr); + } + } + } + } + } + return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); #else - return reinterpret_cast(dlsym(handle_, symbol_name.c_str())); + if(handle_ == RTLD_DEFAULT){ + void * func_ptr = dlsym(handle_, symbol_name.c_str()); + if(func_ptr != nullptr){ + return reinterpret_cast(func_ptr); + }else{ + handle_ = dlopen(target_.c_str(), RTLD_NOW); + if (handle_ != nullptr) { + log::info("Lazy loading library {}", target_, getErrorString()); + }else{ + if(essential_){ + throw std::runtime_error("library " + target_ + " is unavailable on your system."); + } + } + return reinterpret_cast(dlsym(handle_, symbol_name.c_str())); + } + }else{ + return reinterpret_cast(dlsym(handle_, symbol_name.c_str())); + } + #endif } @@ -121,6 +172,8 @@ class DynamicModule { Handle handle_; + std::string target_; + bool essential_; }; } // namespace ion From e5cbb1f2507d6707fa954bf27026fbe18e41fa45 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 29 Aug 2024 10:35:06 -0700 Subject: [PATCH 2/9] fix --- src/bb/image-io/rt_u3v.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bb/image-io/rt_u3v.h b/src/bb/image-io/rt_u3v.h index 9ef8ce57..e04da994 100644 --- a/src/bb/image-io/rt_u3v.h +++ b/src/bb/image-io/rt_u3v.h @@ -4,7 +4,6 @@ #include #include #include -#include #include #include "log.h" From 0a7641e128f207542dfe389038941abd5599ea13 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 29 Aug 2024 10:39:26 -0700 Subject: [PATCH 3/9] typo --- src/bb/image-io/rt_u3v.h | 1 + src/dynamic_module.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bb/image-io/rt_u3v.h b/src/bb/image-io/rt_u3v.h index e04da994..923d1554 100644 --- a/src/bb/image-io/rt_u3v.h +++ b/src/bb/image-io/rt_u3v.h @@ -4,6 +4,7 @@ #include #include #include + #include #include "log.h" diff --git a/src/dynamic_module.h b/src/dynamic_module.h index 3fccad5c..c7165a8e 100644 --- a/src/dynamic_module.h +++ b/src/dynamic_module.h @@ -40,8 +40,8 @@ class DynamicModule { DynamicModule(const std::string& module_name_or_path, bool essential = true, bool lazy_load = false) { if (module_name_or_path == "") { - handle_ = nullptr; - return; + handle_ = nullptr; + return; } // set target From b42e8e0b3e3f745a48e57c98d83066afe1123e89 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 29 Aug 2024 12:50:47 -0700 Subject: [PATCH 4/9] fix windows --- src/dynamic_module.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/dynamic_module.h b/src/dynamic_module.h index c7165a8e..43e2f0f9 100644 --- a/src/dynamic_module.h +++ b/src/dynamic_module.h @@ -71,7 +71,7 @@ class DynamicModule { #endif if (handle_ == nullptr) { if (essential) { - throw std::runtime_error(getErrorString()); + throw std::runtime_error("Library " + target_ + " is unavailable on your system: " + getErrorString()); } else { log::warn("Not found inessential library {} : {}", target, getErrorString()); } @@ -96,23 +96,27 @@ class DynamicModule { if (handle_ != nullptr){ return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); }else{ - Handle hmods[1024]; + Handle hmods[1024]; // the array size should be big enough DWORD cb_needed; if (EnumProcessModules(GetCurrentProcess(), hmods, sizeof(hmods), &cb_needed)) { for (unsigned int i = 0; i < (cb_needed / sizeof(HMODULE)); i++) { char path[MAX_PATH]; // Get the module name if (GetModuleFileNameA(hmods[i], path, sizeof(path) / sizeof(char))) { - // Try to get the address of the symbol in this module - FARPROC func_ptr = GetProcAddress(hmods[i], symbol_name.c_str()); - if (func_ptr != nullptr) { + // Try to get the address of the symbol if module path includes target_ + std::string module_path(path); + if (module_path.find(target_) != std::string::npos) { handle_ = hmods[i]; - return reinterpret_cast(func_ptr); + log::info("Lazy loading library {}", target_, getErrorString()); + return reinterpret_cast(GetProcAddress(hmods[i], symbol_name.c_str())); } } } } } + if(essential_){ + throw std::runtime_error("Library " + target_ + " is unavailable on your system: " + getErrorString()); + } return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); #else if(handle_ == RTLD_DEFAULT){ @@ -125,7 +129,7 @@ class DynamicModule { log::info("Lazy loading library {}", target_, getErrorString()); }else{ if(essential_){ - throw std::runtime_error("library " + target_ + " is unavailable on your system."); + throw std::runtime_error("Library " + target_ + " is unavailable on your system: " + getErrorString()); } } return reinterpret_cast(dlsym(handle_, symbol_name.c_str())); From ead21a6c5d04c70776f017ea0c1addab0d1c1005 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 29 Aug 2024 13:05:50 -0700 Subject: [PATCH 5/9] log --- src/dynamic_module.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dynamic_module.h b/src/dynamic_module.h index 43e2f0f9..455aa778 100644 --- a/src/dynamic_module.h +++ b/src/dynamic_module.h @@ -71,7 +71,7 @@ class DynamicModule { #endif if (handle_ == nullptr) { if (essential) { - throw std::runtime_error("Library " + target_ + " is unavailable on your system: " + getErrorString()); + throw std::runtime_error(getErrorString()); } else { log::warn("Not found inessential library {} : {}", target, getErrorString()); } @@ -115,7 +115,7 @@ class DynamicModule { } } if(essential_){ - throw std::runtime_error("Library " + target_ + " is unavailable on your system: " + getErrorString()); + throw std::runtime_error(getErrorString()); } return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); #else @@ -129,7 +129,7 @@ class DynamicModule { log::info("Lazy loading library {}", target_, getErrorString()); }else{ if(essential_){ - throw std::runtime_error("Library " + target_ + " is unavailable on your system: " + getErrorString()); + throw std::runtime_error(getErrorString()); } } return reinterpret_cast(dlsym(handle_, symbol_name.c_str())); From 4ad29207ed6c1ef09926ece6bb466b1b8e88cc2c Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 29 Aug 2024 15:42:01 -0700 Subject: [PATCH 6/9] clang-format on dynamic.h --- src/dynamic_module.h | 192 +++++++++++++++++++++---------------------- 1 file changed, 93 insertions(+), 99 deletions(-) diff --git a/src/dynamic_module.h b/src/dynamic_module.h index 455aa778..260ee190 100644 --- a/src/dynamic_module.h +++ b/src/dynamic_module.h @@ -5,8 +5,8 @@ #if _WIN32 #define WIN32_LEAN_AND_MEAN -#include #include +#include #define ION_DYNAMIC_MODULE_PREFIX "" #define ION_DYNAMIC_MODULE_EXT ".dll" #elif __APPLE__ @@ -30,61 +30,60 @@ bool has_prefix_and_ext(const std::string& n) { namespace ion { class DynamicModule { - public: - +public: #ifdef _WIN32 - using Handle = HMODULE; + using Handle = HMODULE; #else - using Handle = void*; + using Handle = void *; #endif - DynamicModule(const std::string& module_name_or_path, bool essential = true, bool lazy_load = false) { - if (module_name_or_path == "") { - handle_ = nullptr; - return; - } + DynamicModule(const std::string& module_name_or_path, bool essential = true, bool lazy_load = false) { + if (module_name_or_path == "") { + handle_ = nullptr; + return; + } // set target - std::string target; - if (std::filesystem::exists(module_name_or_path) || has_prefix_and_ext(module_name_or_path)) { - // This is absolute path or file name - target = module_name_or_path; - } else { - target = std::string(ION_DYNAMIC_MODULE_PREFIX) + module_name_or_path + std::string(ION_DYNAMIC_MODULE_EXT); - } - target_ = target; - essential_ = essential; - - if (lazy_load){ + std::string target; + if (std::filesystem::exists(module_name_or_path) || has_prefix_and_ext(module_name_or_path)) { + // This is absolute path or file name + target = module_name_or_path; + } else { + target = std::string(ION_DYNAMIC_MODULE_PREFIX) + module_name_or_path + std::string(ION_DYNAMIC_MODULE_EXT); + } + target_ = target; + essential_ = essential; + + if (lazy_load) { #ifdef _WIN32 - handle_ = nullptr; + handle_ = nullptr; #else - handle_ = RTLD_DEFAULT; + handle_ = RTLD_DEFAULT; #endif - }else{ + } else { - // TODO: WIP: test moduel_name_or_path using std::filesystem + // TODO: WIP: test moduel_name_or_path using std::filesystem #ifdef _WIN32 handle_ = LoadLibraryA(target.c_str()); #else handle_ = dlopen(target.c_str(), RTLD_NOW); #endif if (handle_ == nullptr) { - if (essential) { - throw std::runtime_error(getErrorString()); - } else { - log::warn("Not found inessential library {} : {}", target, getErrorString()); - } - } - } - } - - ~DynamicModule() { - if (handle_ != nullptr) { - // NOTE: DSO which is loaded by with_bb_module should not be unloaded even if Builder is destructed. - // Loading more than twice does not have any side effects. - } - } + if (essential) { + throw std::runtime_error(getErrorString()); + } else { + log::warn("Not found inessential library {} : {}", target, getErrorString()); + } + } + } + } + + ~DynamicModule() { + if (handle_ != nullptr) { + // NOTE: DSO which is loaded by with_bb_module should not be unloaded even if Builder is destructed. + // Loading more than twice does not have any side effects. + } + } bool is_available(void) const { return handle_ != nullptr; @@ -93,9 +92,9 @@ class DynamicModule { template T get_symbol(const std::string &symbol_name) { #ifdef _WIN32 - if (handle_ != nullptr){ - return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); - }else{ + if (handle_ != nullptr) { + return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); + } else { Handle hmods[1024]; // the array size should be big enough DWORD cb_needed; if (EnumProcessModules(GetCurrentProcess(), hmods, sizeof(hmods), &cb_needed)) { @@ -113,73 +112,68 @@ class DynamicModule { } } } - } - if(essential_){ - throw std::runtime_error(getErrorString()); - } - return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); + } + if (essential_) { + throw std::runtime_error(getErrorString()); + } + return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); #else - if(handle_ == RTLD_DEFAULT){ - void * func_ptr = dlsym(handle_, symbol_name.c_str()); - if(func_ptr != nullptr){ - return reinterpret_cast(func_ptr); - }else{ - handle_ = dlopen(target_.c_str(), RTLD_NOW); - if (handle_ != nullptr) { - log::info("Lazy loading library {}", target_, getErrorString()); - }else{ - if(essential_){ - throw std::runtime_error(getErrorString()); - } - } - return reinterpret_cast(dlsym(handle_, symbol_name.c_str())); + if (handle_ == RTLD_DEFAULT) { + void *func_ptr = dlsym(handle_, symbol_name.c_str()); + if (func_ptr != nullptr) { + return reinterpret_cast(func_ptr); + } else { + handle_ = dlopen(target_.c_str(), RTLD_NOW); + if (handle_ != nullptr) { + log::info("Lazy loading library {}", target_, getErrorString()); + } else { + if (essential_) { + throw std::runtime_error(getErrorString()); + } + } + return reinterpret_cast(dlsym(handle_, symbol_name.c_str())); } - }else{ - return reinterpret_cast(dlsym(handle_, symbol_name.c_str())); - } + } else { + return reinterpret_cast(dlsym(handle_, symbol_name.c_str())); + } #endif } - - private: - - std::string getErrorString(void) const { - std::string error_msg; +private: + std::string getErrorString(void) const { + std::string error_msg; #ifdef _WIN32 - DWORD error = GetLastError(); - if (error) - { - LPVOID lpMsgBuf; - DWORD bufLen = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, - error, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (LPTSTR) &lpMsgBuf, 0, nullptr ); - if (bufLen) - { - LPCSTR lpMsgStr = (LPCSTR)lpMsgBuf; - error_msg = std::string(lpMsgStr, lpMsgStr+bufLen); - LocalFree(lpMsgBuf); - } - } + DWORD error = GetLastError(); + if (error) { + LPVOID lpMsgBuf; + DWORD bufLen = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + error, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + (LPTSTR)&lpMsgBuf, 0, nullptr); + if (bufLen) { + LPCSTR lpMsgStr = (LPCSTR)lpMsgBuf; + error_msg = std::string(lpMsgStr, lpMsgStr + bufLen); + LocalFree(lpMsgBuf); + } + } #else - const char* buf(dlerror()); - error_msg.assign(buf ? buf : "none"); + const char *buf(dlerror()); + error_msg.assign(buf ? buf : "none"); #endif - return error_msg; - } - + return error_msg; + } - Handle handle_; - std::string target_; - bool essential_; + Handle handle_; + std::string target_; + bool essential_; }; -} // namespace ion +} // namespace ion -#endif // ION_DYNAMIC_MODULE_H +#endif // ION_DYNAMIC_MODULE_H From 03c211698531a450dd4fb82485d7561c0798f8ea Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 29 Aug 2024 16:09:36 -0700 Subject: [PATCH 7/9] fix cdci --- src/dynamic_module.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dynamic_module.h b/src/dynamic_module.h index 260ee190..d79bb1dc 100644 --- a/src/dynamic_module.h +++ b/src/dynamic_module.h @@ -5,8 +5,8 @@ #if _WIN32 #define WIN32_LEAN_AND_MEAN -#include #include +#include #define ION_DYNAMIC_MODULE_PREFIX "" #define ION_DYNAMIC_MODULE_EXT ".dll" #elif __APPLE__ From d01260091473103d997044c1c45b697ec680d484 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Fri, 30 Aug 2024 10:15:43 -0700 Subject: [PATCH 8/9] fix windows --- src/dynamic_module.h | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/dynamic_module.h b/src/dynamic_module.h index d79bb1dc..1e29de6d 100644 --- a/src/dynamic_module.h +++ b/src/dynamic_module.h @@ -95,7 +95,8 @@ class DynamicModule { if (handle_ != nullptr) { return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); } else { - Handle hmods[1024]; // the array size should be big enough + // search symbol globally first + Handle hmods[1024]; // the array size should be large enough DWORD cb_needed; if (EnumProcessModules(GetCurrentProcess(), hmods, sizeof(hmods), &cb_needed)) { for (unsigned int i = 0; i < (cb_needed / sizeof(HMODULE)); i++) { @@ -106,17 +107,22 @@ class DynamicModule { std::string module_path(path); if (module_path.find(target_) != std::string::npos) { handle_ = hmods[i]; - log::info("Lazy loading library {}", target_, getErrorString()); return reinterpret_cast(GetProcAddress(hmods[i], symbol_name.c_str())); } } } } + // failed to load symbol gloablly, load it explicitly + handle_ = LoadLibraryA(target_.c_str()); + if (handle_ != nullptr) { + log::info("Lazy loading library {}", target_, getErrorString()); + } else { + if (essential_) { + throw std::runtime_error(getErrorString()); + } + } + return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); } - if (essential_) { - throw std::runtime_error(getErrorString()); - } - return reinterpret_cast(GetProcAddress(handle_, symbol_name.c_str())); #else if (handle_ == RTLD_DEFAULT) { void *func_ptr = dlsym(handle_, symbol_name.c_str()); @@ -136,7 +142,6 @@ class DynamicModule { } else { return reinterpret_cast(dlsym(handle_, symbol_name.c_str())); } - #endif } From ace51427eff7f3b9679e90f0b26e83ef7db7b505 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Fri, 30 Aug 2024 13:42:40 -0700 Subject: [PATCH 9/9] fix --- src/dynamic_module.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dynamic_module.h b/src/dynamic_module.h index 1e29de6d..ed0bdd83 100644 --- a/src/dynamic_module.h +++ b/src/dynamic_module.h @@ -115,7 +115,7 @@ class DynamicModule { // failed to load symbol gloablly, load it explicitly handle_ = LoadLibraryA(target_.c_str()); if (handle_ != nullptr) { - log::info("Lazy loading library {}", target_, getErrorString()); + log::info("Lazy loading library {}", target_); } else { if (essential_) { throw std::runtime_error(getErrorString()); @@ -131,7 +131,7 @@ class DynamicModule { } else { handle_ = dlopen(target_.c_str(), RTLD_NOW); if (handle_ != nullptr) { - log::info("Lazy loading library {}", target_, getErrorString()); + log::info("Lazy loading library {}", target_); } else { if (essential_) { throw std::runtime_error(getErrorString());