Skip to content

Commit 337dad9

Browse files
committed
Since we can't redistribute vciapi.dll for the HMS Ixxat VCI driver, we load it only if it is required. #5
1 parent 8ca1c9b commit 337dad9

3 files changed

Lines changed: 54 additions & 7 deletions

File tree

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,21 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/deps.cmake)
2424

2525
target_link_libraries(
2626
${PROJECT_NAME}
27+
PRIVATE
2728
${PLATFORM_LIBS}
2829
)
2930

31+
if(WIN32 AND MSVC)
32+
# Ensure the library can be loaded without vciapi.dll present.
33+
# vciapi.dll will only be loaded when an Ixxat (VCI) function is called.
34+
target_link_options(${PROJECT_NAME} PRIVATE /DELAYLOAD:vciapi.dll)
35+
target_link_libraries(${PROJECT_NAME} PRIVATE delayimp)
36+
endif()
37+
3038
if(UNIX)
3139
target_link_libraries(
3240
${PROJECT_NAME}
41+
PRIVATE
3342
socketcan
3443
)
3544

cmake/deps.cmake

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ if(WIN32)
2727

2828
BUILD_COMMAND ${CMAKE_COMMAND} -E echo "Skipping build step."
2929

30-
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy
31-
${IXXAT_PATH}/sdk/vci/bin/${IXXAT_PLATFORM}/release/vciapi.dll ${CMAKE_CURRENT_BINARY_DIR}/
30+
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Skipping install step."
3231

3332
PATCH_COMMAND ${CMAKE_COMMAND} -E copy
3433
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/dep_ixxat.cmake" ${IXXAT_PATH}/CMakeLists.txt

src/CANvenient.c

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@
88
*
99
**/
1010

11+
#include <stdbool.h>
1112
#include <stdio.h>
1213
#include <stdlib.h>
14+
#ifdef _WIN32
15+
#include <windows.h>
16+
#endif
1317

1418
#include "CANvenient.h"
1519
#include "drivers/CANvenient_internal.h"
@@ -19,6 +23,11 @@
1923
#include "drivers/CANvenient_Softing.h"
2024
#include "drivers/CANvenient_PEAK.h"
2125

26+
#ifdef _WIN32
27+
static HMODULE vciapi_dll_handle = NULL;
28+
static bool is_vciapi_dll_available = false;
29+
#endif
30+
2231
struct can_iface can_interface[CAN_MAX_INTERFACES] = {0};
2332
char can_error_reason[1024] = {0};
2433

@@ -29,10 +38,37 @@ CANVENIENT_API int can_find_interfaces_mask(u32 vendor_mask)
2938
return 0;
3039
}
3140

32-
if (vendor_mask & CAN_VENDOR_IXXAT)
41+
#ifdef _WIN32
42+
static bool once_checked_vciapi_dll = false;
43+
44+
// https://github.com/CANopenTerm/CANopenTerm/issues/109#issuecomment-4320171025
45+
if (! once_checked_vciapi_dll)
46+
{
47+
if (GetFileAttributesA("vciapi.dll") != INVALID_FILE_ATTRIBUTES)
48+
{
49+
vciapi_dll_handle = LoadLibraryA("vciapi.dll");
50+
if (! vciapi_dll_handle)
51+
{
52+
puts("vciapi.dll not found. Ixxat interfaces will be ignored.");
53+
is_vciapi_dll_available = false;
54+
}
55+
else
56+
{
57+
is_vciapi_dll_available = true;
58+
}
59+
}
60+
else
61+
{
62+
puts("vciapi.dll not found. Ixxat interfaces will be ignored.");
63+
}
64+
65+
once_checked_vciapi_dll = true;
66+
}
67+
if (vendor_mask & CAN_VENDOR_IXXAT && is_vciapi_dll_available)
3368
{
3469
ixxat_find_interfaces();
3570
}
71+
3672
if (vendor_mask & CAN_VENDOR_PEAK)
3773
{
3874
peak_find_interfaces();
@@ -41,14 +77,17 @@ CANVENIENT_API int can_find_interfaces_mask(u32 vendor_mask)
4177
{
4278
kvaser_find_interfaces();
4379
}
44-
if (vendor_mask & CAN_VENDOR_SOCKETCAN)
45-
{
46-
socketcan_find_interfaces();
47-
}
80+
4881
if (vendor_mask & CAN_VENDOR_SOFTING)
4982
{
5083
softing_find_interfaces();
5184
}
85+
#endif
86+
87+
if (vendor_mask & CAN_VENDOR_SOCKETCAN)
88+
{
89+
socketcan_find_interfaces();
90+
}
5291

5392
return 0;
5493
}

0 commit comments

Comments
 (0)