Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

c++ wrapper for libusb, add try/catch to prevent app crashes #63

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
d45082a
clean refLibusbDeviceByName(), usb_host.cpp mutex, mxid_cache
diablodale May 17, 2023
0811a8a
initial c++ wrapper for libusb; for libusb_get_device_list()
diablodale May 17, 2023
761fb22
add dai namespace to libusb wrappers
diablodale May 18, 2023
114eae6
add dai::libusb::usb_error exception class
diablodale May 18, 2023
987f212
add dai::libusb::config_descriptor wrapper class
diablodale May 18, 2023
c2dd35a
add dai::libusb::usb_device, dai::libusb::device_handle
diablodale May 18, 2023
31e856b
remove dai::device_list::create() factory
diablodale May 18, 2023
b64fe62
add dai::libusb::device_handle::claim_interface()
diablodale May 18, 2023
9374b5b
updates to enable C++11
diablodale May 18, 2023
265be7f
add dai::out_param to simplify use of wrappers with C-functions
diablodale May 19, 2023
6086999
fix test multiple_open_stream - uninitialized structs
diablodale May 20, 2023
526113a
refactor for dai::out_param, more RAII, some params now wrappers
diablodale May 19, 2023
1adf607
simplify libusb wrapper
diablodale May 20, 2023
3926426
change libusb wrap macros -> template function
diablodale May 20, 2023
9deed2a
add libusb::device_handle:: get/set_configuration
diablodale May 20, 2023
56dcf33
add libusb::device_handle::set_auto_detach_kernel_driver
diablodale May 20, 2023
c835049
add libusb::usb_context and automatic libusb_exit() on app close
diablodale May 20, 2023
5a7a050
add libusb::usb_device::get_config_descriptor()
diablodale May 20, 2023
6271d47
fix call_log_throw() exception specifier with tag dispatch
diablodale May 20, 2023
de46723
add usb_device:: {}, open, reset, get_device_descriptor
diablodale May 20, 2023
dae7906
refactor getUSBDevices(); more usb_device, exceptions, RAII
diablodale May 20, 2023
b0e3834
add usb_device::get_bus_number, get_port_numbers
diablodale May 20, 2023
d3c0cfe
fix thread-unsafe libusb_get_device_list(); add get_string_descriptor…
diablodale May 21, 2023
70fc4d9
send bcdUSB to usb_boot(); add set_max_packet_size()
diablodale May 22, 2023
987049a
add noexcept specs to libusb wrappers
diablodale May 22, 2023
d224375
update usb_open_device() to not update handle on errors
diablodale May 22, 2023
25eb61a
add bulk_transfer() and cleanup; not yet complete
diablodale May 24, 2023
533c22b
bulk_transfer work: containers, bugfixes, cleanup
diablodale May 24, 2023
b5fc5ad
fix bulk_transfer() and refactor usb_host.cpp to use it
diablodale May 25, 2023
39a5a44
refactor usb_boot(), usbLinkOpen() to use libusb wrappers
diablodale May 25, 2023
a60a6c4
add control_transfer() and use in usbLinkBootBootloader()
diablodale May 25, 2023
a546d38
change vidpid->state container to std::array
diablodale May 25, 2023
4cdadec
shorter lock for usb_mx_id_cache; minor tidy changes
diablodale May 26, 2023
48757aa
refactor usb open-ish functions for exception handling
diablodale May 26, 2023
47c4874
enable c++14 standard in cmake; remove backports for c++11
diablodale May 26, 2023
4cdd87f
add exception handling to usbInitialize()
diablodale May 26, 2023
766c483
add libusb wrapper license and change namespace to dp
diablodale May 26, 2023
efe8315
add getUSBDevices() exception handling
diablodale May 26, 2023
48a09af
add wrapper project name to (c)
diablodale May 26, 2023
78bf941
wrapper clarified noexcept and bulk_transfer return type
diablodale May 27, 2023
d5280e3
add exception handling for usbPlatform* functions
diablodale May 27, 2023
1ebdd66
return several log levels to production setting
diablodale May 27, 2023
ccfd20d
refactor ***PlatformDeviceFdFromKey(), exceptions, and race condition
diablodale May 27, 2023
ab44cf7
add ".0" to path for HCD's with no ports
diablodale May 27, 2023
7c60f00
libusb wrapper use constexpr array; persist usbBCD
diablodale May 28, 2023
d811294
refactor libusb wrapper device_handle move(s)
diablodale May 28, 2023
4e09f32
add logging to ***PlatformDeviceFdFromKey()
diablodale May 28, 2023
1e00dba
fix device_handle constructors, reset(), bcdUSB
diablodale May 28, 2023
bb4ae36
simplify device_handle::get_string_descriptor_ascii()
diablodale May 28, 2023
45bcb15
add debug log, comments, clearer var names
diablodale May 28, 2023
2e947aa
calc+persist chunkSize instead of bcdUSB
diablodale May 29, 2023
4054fc6
add getPlatformDeviceFdFromKeySimple(void*)
diablodale May 29, 2023
659678c
add RAII in usbPlatformConnect,Close,Read,Write
diablodale May 29, 2023
9cabf73
remove double-spaces in mvLog() calls
diablodale May 29, 2023
e99a13f
libusb wrapper workaround for Clang constexpr fails
diablodale May 29, 2023
147d61a
fix add_flag() to correctly add flags to C++ files
diablodale May 30, 2023
860699f
fix errant macro define of system reserved __attribute__
diablodale May 30, 2023
ab63c51
move some libusb wrapper headers to cpp file
diablodale May 30, 2023
ee3e53e
fix libusb bug in libusb_free_device_list(ptr, 1)
diablodale May 31, 2023
81d473c
libusb wrapper resources support nullptr as contents
diablodale May 31, 2023
eb7d4da
add doc for libusb wrappers
diablodale May 31, 2023
ae17b7a
more libusb wrapper container functions
diablodale Jun 1, 2023
6ad36b6
refactor libusb::span to be more std::span
diablodale Jun 1, 2023
d1e177b
libusb::device_list::iterator::operator*() -> usb_device
diablodale Jun 2, 2023
3313b16
use simplified libusb::device_list w/ its direct usb_device deref
diablodale Jun 2, 2023
fd73cfa
update ZLP test for libusb wrapper bulk_transfer
diablodale Jun 2, 2023
de53772
libusb wrapper doxygen and minor return value cleanup
diablodale Jun 4, 2023
b328c1a
debug assert usb device list contains only non-null devices
diablodale Jun 4, 2023
2ae8877
libusb wrapper constructor and doc cleanup
diablodale Jun 8, 2023
0aaf58a
mac clang workaround for inheriting base constructors
diablodale Jun 8, 2023
be19c74
add mermaid diagram to libusb wrapper docs
diablodale Jul 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0
# With additions of Luxonis

cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.3)

include("cmake/HunterGate.cmake")
HunterGate(
Expand Down Expand Up @@ -82,7 +82,7 @@ else()
endif()

if(WIN32)
target_compile_definitions(${TARGET_NAME} PRIVATE WIN32_LEAN_AND_MEAN)
target_compile_definitions(${TARGET_NAME} PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX)
else()
find_package(Threads REQUIRED)
target_link_libraries(${TARGET_NAME} PRIVATE Threads::Threads)
Expand Down Expand Up @@ -140,18 +140,19 @@ endif()

# Set C99 standard
set_property(TARGET ${TARGET_NAME} PROPERTY C_STANDARD 99)
# Set compiler features (c++11), and disables extensions (g++11)
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD 11)
# Set compiler features (c++14), and disables extensions (g++14)
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD 14)
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_EXTENSIONS OFF)
# Add interface transitive property (C++11) to public library
# Add interface transitive property (C++14) to public library
if(${CMAKE_VERSION} VERSION_LESS "3.8.0")
target_compile_features(${TARGET_PUBLIC_NAME} INTERFACE cxx_range_for)
target_compile_features(${TARGET_PUBLIC_NAME} INTERFACE cxx_generic_lambdas)
else()
target_compile_features(${TARGET_PUBLIC_NAME} INTERFACE cxx_std_11)
target_compile_features(${TARGET_PUBLIC_NAME} INTERFACE cxx_std_14)
endif()

# Add flags
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_default_flags(${TARGET_NAME})

# Check if pthread_getname_np exists
Expand Down
6 changes: 6 additions & 0 deletions cmake/Flags.cmake
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
## setup compilation flags
# conditionally applies flag. If flag is supported by current compiler, it will be added to compile options.
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
function(add_flag target flag)
check_c_compiler_flag(${flag} FLAG_${flag})
if (FLAG_${flag} EQUAL 1)
target_compile_options(${target} PRIVATE $<$<COMPILE_LANGUAGE:C>:${flag}>)
endif ()
check_cxx_compiler_flag(${flag} FLAGXX_${flag})
if (FLAGXX_${flag} EQUAL 1)
target_compile_options(${target} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${flag}>)
endif ()
endfunction()

# only works for C source files
function(add_flag_source source flag)
check_c_compiler_flag(${flag} FLAG_${flag})
if (FLAG_${flag} EQUAL 1)
Expand Down
2 changes: 1 addition & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
macro(add_example example_name example_src)
add_executable(${example_name} ${example_src})
target_link_libraries(${example_name} ${TARGET_NAME})
set_property(TARGET ${example_name} PROPERTY CXX_STANDARD 11)
set_property(TARGET ${example_name} PROPERTY CXX_STANDARD 14)
set_property(TARGET ${example_name} PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET ${example_name} PROPERTY CXX_EXTENSIONS OFF)

Expand Down
6 changes: 3 additions & 3 deletions include/XLink/XLinkErrorUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extern "C"
#ifndef ASSERT_XLINK
#define ASSERT_XLINK(condition) do { \
if(!(condition)) { \
mvLog(MVLOG_ERROR, "Assertion Failed: %s \n", #condition); \
mvLog(MVLOG_ERROR, "Assertion Failed: %s", #condition); \
return X_LINK_ERROR; \
} \
} while(0)
Expand All @@ -26,7 +26,7 @@ extern "C"
#ifndef ASSERT_XLINK
#define ASSERT_XLINK(condition) do { \
if(!(condition)) { \
mvLog(MVLOG_ERROR, "Assertion Failed: %s \n", #condition); \
mvLog(MVLOG_ERROR, "Assertion Failed: %s", #condition); \
exit(EXIT_FAILURE); \
} \
} while(0)
Expand Down Expand Up @@ -88,7 +88,7 @@ extern "C"
#define XLINK_OUT_IF(condition) do { \
\
XLINK_OUT_WITH_LOG_IF((condition), \
mvLog(MVLOG_ERROR, "Condition failed: %s \n", #condition));\
mvLog(MVLOG_ERROR, "Condition failed: %s", #condition));\
\
} while(0)
#endif // XLINK_OUT_IF
Expand Down
20 changes: 13 additions & 7 deletions include/XLink/XLinkLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,18 @@ typedef enum mvLog_t{
MVLOG_LAST,
} mvLog_t;

// Windows-only
#if (defined (WINNT) || defined(_WIN32) || defined(_WIN64) )
#define __attribute__(x)
#define FUNCATTR_WEAK static
// attribute directive support test
#if defined(__has_attribute)
# define MVLOG_ATTRIBUTE(x) __attribute__(x)
// weak function support test
# if __has_attribute(weak)
# define FUNCATTR_WEAK
# else
# define FUNCATTR_WEAK static
# endif
#else
#define FUNCATTR_WEAK
# define MVLOG_ATTRIBUTE(x)
# define FUNCATTR_WEAK static
#endif

#define _MVLOGLEVEL(UNIT_NAME) mvLogLevel_ ## UNIT_NAME
Expand All @@ -61,7 +67,7 @@ typedef enum mvLog_t{
#ifndef MVLOG_UNIT_NAME
#define MVLOG_UNIT_NAME global
#else
FUNCATTR_WEAK mvLog_t __attribute__ ((weak)) MVLOGLEVEL(MVLOG_UNIT_NAME) = MVLOG_LAST;
FUNCATTR_WEAK mvLog_t MVLOG_ATTRIBUTE((weak)) MVLOGLEVEL(MVLOG_UNIT_NAME) = MVLOG_LAST;
#endif


Expand All @@ -75,7 +81,7 @@ FUNCATTR_WEAK mvLog_t __attribute__ ((weak)) MVLOGLEVEL(MVLOG_UNIT_NAME) = MVLOG
extern mvLog_t MVLOGLEVEL(global);
extern mvLog_t MVLOGLEVEL(default);

int __attribute__ ((unused)) logprintf(mvLog_t curLogLvl, mvLog_t lvl, const char * func, const int line, const char * format, ...);
int MVLOG_ATTRIBUTE((unused)) logprintf(mvLog_t curLogLvl, mvLog_t lvl, const char * func, const int line, const char * format, ...);

#define mvLog(lvl, format, ...) \
logprintf(MVLOGLEVEL(MVLOG_UNIT_NAME), lvl, __func__, __LINE__, format, ##__VA_ARGS__)
Expand Down
4 changes: 2 additions & 2 deletions include/XLink/XLinkPlatformErrorUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extern "C"
#ifndef ASSERT_XLINK_PLATFORM_R
#define ASSERT_XLINK_PLATFORM_R(condition, err) do { \
if(!(condition)) { \
mvLog(MVLOG_ERROR, "Assertion Failed: %s \n", #condition); \
mvLog(MVLOG_ERROR, "Assertion Failed: %s", #condition); \
return (err); \
} \
} while(0)
Expand All @@ -34,7 +34,7 @@ extern "C"
#ifndef ASSERT_XLINK_PLATFORM_R
#define ASSERT_XLINK_PLATFORM_R(condition, err) do { \
if(!(condition)) { \
mvLog(MVLOG_ERROR, "Assertion Failed: %s \n", #condition); \
mvLog(MVLOG_ERROR, "Assertion Failed: %s", #condition); \
exit(EXIT_FAILURE); \
} \
} while(0)
Expand Down
2 changes: 1 addition & 1 deletion src/pc/PlatformDeviceControl.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int usbFdRead = -1;
#include "XLinkPublicDefines.h"

#define USB_LINK_SOCKET_PORT 5678
#define UNUSED __attribute__((unused))
#define UNUSED MVLOG_ATTRIBUTE((unused))


static UsbSpeed_t usb_speed_enum = X_LINK_USB_SPEED_UNKNOWN;
Expand Down
108 changes: 83 additions & 25 deletions src/pc/PlatformDeviceFd.cpp
Original file line number Diff line number Diff line change
@@ -1,44 +1,102 @@
#define MVLOG_UNIT_NAME xLinkUsb

#include "PlatformDeviceFd.h"
#include "XLink/XLinkLog.h"

#include <unordered_map>
#include <atomic>
#include <mutex>
#include <cstdint>
#include <mutex>
#include <unordered_map>

static std::mutex mutex;
static std::unordered_map<std::uintptr_t, void*> map;
static std::uintptr_t uniqueFdKey{0x55};

int getPlatformDeviceFdFromKey(void* fdKeyRaw, void** fd){
if(fd == nullptr) return -1;
std::unique_lock<std::mutex> lock(mutex);

std::uintptr_t fdKey = reinterpret_cast<std::uintptr_t>(fdKeyRaw);
if(map.count(fdKey) > 0){
*fd = map.at(fdKey);
// Returns the mapped fd value of the element with key equivalent to fdKeyRaw
// Non-zero return value indicates failure
int getPlatformDeviceFdFromKey(void* const fdKeyRaw, void** const fd) noexcept {
if(fd == nullptr) {
mvLog(MVLOG_ERROR, "getPlatformDeviceFdFromKey/Simple(%p) failed", fdKeyRaw);
return -1;
}
try {
const std::lock_guard<std::mutex> lock(mutex);
const auto result = map.find(reinterpret_cast<std::uintptr_t>(fdKeyRaw));
if(result == map.end()) {
mvLog(MVLOG_ERROR, "getPlatformDeviceFdFromKey/Simple(%p) failed", fdKeyRaw);
return 1;
}
*fd = result->second;
//mvLog(MVLOG_DEBUG, "getPlatformDeviceFdFromKey(%p) result %p", fdKeyRaw, *fd);
return 0;
} else {
return 1;
} catch(std::exception&) {
mvLog(MVLOG_ERROR, "getPlatformDeviceFdFromKey/Simple(%p) failed", fdKeyRaw);
return -1;
}
}

void* createPlatformDeviceFdKey(void* fd){
std::unique_lock<std::mutex> lock(mutex);

// Get uniqueFdKey
std::uintptr_t fdKey = uniqueFdKey++;
map[fdKey] = fd;
return reinterpret_cast<void*>(fdKey);
// Returns the mapped fd value of the element with key equivalent to fdKeyRaw
// returns nullptr when not found, failure, or createPlatformDeviceFdKey(nullptr) was used
void* getPlatformDeviceFdFromKeySimple(void* const fdKeyRaw) noexcept {
void* fd = nullptr;
getPlatformDeviceFdFromKey(fdKeyRaw, &fd);
return fd;
}

int destroyPlatformDeviceFdKey(void* fdKeyRaw){
std::unique_lock<std::mutex> lock(mutex);
// Inserts a copy of value fd into an associative container with key fdKeyRaw
// nullptr return value indicates failure
void* createPlatformDeviceFdKey(void* const fd) noexcept {
try {
const std::lock_guard<std::mutex> lock(mutex);
const std::uintptr_t fdKey = uniqueFdKey++; // Get a unique key
map[fdKey] = fd;
mvLog(MVLOG_DEBUG, "createPlatformDeviceFdKey(%p) result %p", fd, reinterpret_cast<void*>(fdKey));
return reinterpret_cast<void*>(fdKey);
} catch(std::exception&) {
mvLog(MVLOG_ERROR, "createPlatformDeviceFdKey(%p) failed", fd);
return nullptr;
}
}

std::uintptr_t fdKey = reinterpret_cast<std::uintptr_t>(fdKeyRaw);
if(map.count(fdKey) > 0){
map.erase(fdKey);
return 0;
} else {
// Removes the element (if one exists) with the key equivalent to fdKeyRaw
// Non-zero return value indicates failure
int destroyPlatformDeviceFdKey(void* const fdKeyRaw) noexcept {
try {
std::lock_guard<std::mutex> lock(mutex);
const auto result = map.erase(reinterpret_cast<std::uintptr_t>(fdKeyRaw));
if (result == 0)
mvLog(MVLOG_ERROR, "destroyPlatformDeviceFdKey(%p) failed", fdKeyRaw);
else
mvLog(MVLOG_DEBUG, "destroyPlatformDeviceFdKey(%p) success", fdKeyRaw);
return !result;
} catch(std::exception&) {
mvLog(MVLOG_ERROR, "destroyPlatformDeviceFdKey(%p) failed", fdKeyRaw);
return -1;
}
}

// Extracts (finds and removes) the element (if one exists) with the key equivalent to fdKeyRaw
// nullptr return value indicates failure
// Only one mutex lock is taken compared to separate getPlatformDeviceFdFromKey() then destroyPlatformDeviceFdKey().
// Additionally, this atomic operation prevents a set of race conditions of two threads when
// each get() and/or destroy() keys in unpredictable orders.
void* extractPlatformDeviceFdKey(void* const fdKeyRaw) noexcept {
try {
std::lock_guard<std::mutex> lock(mutex);
const auto result = map.find(reinterpret_cast<std::uintptr_t>(fdKeyRaw));
if(result == map.end()) {
mvLog(MVLOG_ERROR, "extractPlatformDeviceFdKey(%p) failed", fdKeyRaw);
return nullptr;
}
const auto fd = result->second;
map.erase(result);
mvLog(MVLOG_DEBUG, "extractPlatformDeviceFdKey(%p) success", fdKeyRaw);
return fd;
} catch(std::exception&) {
mvLog(MVLOG_ERROR, "extractPlatformDeviceFdKey(%p) failed", fdKeyRaw);
return nullptr;
}
}

// TODO consider storing the device_handle in the fdKey store with std::map<device_handle> so that
// it can automatically handle refcounting, interfaces, and closing
14 changes: 9 additions & 5 deletions src/pc/PlatformDeviceFd.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
#define _PLATFORM_DEVICE_FD_H_

#ifdef __cplusplus
extern "C"
{
#define NOEXCEPT noexcept
extern "C" {
#else
#define NOEXCEPT
#endif

int getPlatformDeviceFdFromKey(void* fdKeyRaw, void** fd);
void* createPlatformDeviceFdKey(void* fd);
int destroyPlatformDeviceFdKey(void* fdKeyRaw);
int getPlatformDeviceFdFromKey(void* fdKeyRaw, void** fd) NOEXCEPT;
void* getPlatformDeviceFdFromKeySimple(void* fdKeyRaw) NOEXCEPT;
void* createPlatformDeviceFdKey(void* fd) NOEXCEPT;
int destroyPlatformDeviceFdKey(void* fdKeyRaw) NOEXCEPT;
void* extractPlatformDeviceFdKey(void* fdKeyRaw) NOEXCEPT;

#ifdef __cplusplus
}
Expand Down
6 changes: 3 additions & 3 deletions src/pc/PlatformDeviceSearchDynamic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

extern "C" xLinkPlatformErrorCode_t getUSBDevices(const deviceDesc_t in_deviceRequirements,
deviceDesc_t* out_foundDevices, int sizeFoundDevices,
unsigned int *out_amountOfFoundDevices);
unsigned int *out_amountOfFoundDevices) noexcept;

xLinkPlatformErrorCode_t XLinkPlatformFindDevicesDynamic(const deviceDesc_t in_deviceRequirements,
deviceDesc_t* out_foundDevices, unsigned sizeFoundDevices,
Expand Down Expand Up @@ -138,9 +138,9 @@ xLinkPlatformErrorCode_t XLinkPlatformFindDevicesDynamic(const deviceDesc_t in_d
{
deviceDesc_t* devices = out_foundDevices;
int write_index = 0;
for(int i = 0; i < *out_amountOfFoundDevices; i++){
for(int i = 0, amountBound = static_cast<int>(*out_amountOfFoundDevices); i < amountBound; ++i){
bool duplicate = false;
for(int j = i - 1; j >= 0; j--){
for(int j = i - 1; j >= 0; --j){
// Check if duplicate
if(devices[i].protocol == devices[j].protocol && strcmp(devices[i].name, devices[j].name) == 0 && strcmp(devices[i].mxid, devices[j].mxid) == 0){
duplicate = true;
Expand Down
7 changes: 4 additions & 3 deletions src/pc/Win/src/win_usb_host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
#include <array>
#include <pathcch.h>

int usbInitialize_customdir(void** hContext) {
// support Visual C++ compiler for Windows to load libusb DLL from the same directory as the XLink code
libusb_error usbInitializeCustomdir(libusb_context ** hContext) noexcept {
// get handle to the module containing a XLink static function/var
// can not use GetModuleFileNameW(nullptr) because when the main depthai app is a DLL (e.g. plugin),
// then it returns the main EXE which is usually wrong
Expand Down Expand Up @@ -57,9 +58,9 @@ int usbInitialize_customdir(void** hContext) {
}

// initialize libusb
int initResult = LIBUSB_SUCCESS;
libusb_error initResult = LIBUSB_SUCCESS;
__try {
initResult = libusb_init((libusb_context**)hContext);
initResult = static_cast<libusb_error>(libusb_init(hContext));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
initResult = LIBUSB_ERROR_OVERFLOW;
Expand Down
Loading