From a706a2e36e74230748c84436584156399d445286 Mon Sep 17 00:00:00 2001 From: juarezr Date: Mon, 6 Jul 2026 10:40:02 +0200 Subject: [PATCH 1/5] Fix warning C4566 on MSVC - UTF-8 string literals need to have u8 prefix to them. --- AdsLib/MasterDcStatAccess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AdsLib/MasterDcStatAccess.cpp b/AdsLib/MasterDcStatAccess.cpp index 141bb846..d13f82fa 100644 --- a/AdsLib/MasterDcStatAccess.cpp +++ b/AdsLib/MasterDcStatAccess.cpp @@ -69,7 +69,7 @@ long MasterDcStatAccess::Print(std::ostream &os) const sizeof(stat.posArr) / sizeof(stat.posArr[0])> rowNames{ { "1", "2", "5", "10", "20", "50", "100", "200", "500", - "\u221E" // infinity symbol + u8"\u221E" // infinity symbol } }; os << "Deviation <" << " | " << "Count (neg)" << " | " << "Count (pos)" From c002ec7fe74b4821265a146fbb1585faad1400b2 Mon Sep 17 00:00:00 2001 From: juarezr Date: Mon, 6 Jul 2026 11:13:27 +0200 Subject: [PATCH 2/5] Small cmake issues - AdsLibTestRef fails to build under linux. The test is only meant to be compile for Windows and FreeBSD systems and should be skiped in all other cases. - Remove warnings and TODOs from FindTcAdsDll.cmake as the case has now been tested and seems to be working. - Fix typos on TwinCAT spelling. --- AdsLibTestRef/CMakeLists.txt | 4 ++++ CMakeLists.txt | 4 ++-- cmake/FindTcAdsDll.cmake | 8 +------- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/AdsLibTestRef/CMakeLists.txt b/AdsLibTestRef/CMakeLists.txt index 247ad0c3..406afde2 100644 --- a/AdsLibTestRef/CMakeLists.txt +++ b/AdsLibTestRef/CMakeLists.txt @@ -2,6 +2,10 @@ if (NOT TcAdsDll_FOUND) return() endif () +# Skip this test if we are not on Windows or FreeBSD system +if (NOT CMAKE_SYSTEM_NAME STREQUAL "Windows" AND NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + return() +endif () set(SOURCES main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5da5bc91..9ea57a2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,14 +36,14 @@ include(GNUInstallDirs) option(WITH_EXAMPLES "Build the examples (for the variant)" ON) option(WITH_TESTS "Build the test (for the variant)" ON) -option(STANDALONE_ONLY "Build only the AdsLib as stand alone (no TwinCat TcAdsDll targets)" OFF) +option(STANDALONE_ONLY "Build only the AdsLib as stand alone (no TwinCAT TcAdsDll targets)" OFF) #Find the needed dependencies find_package(Threads REQUIRED) if (NOT STANDALONE_ONLY) find_package(TcAdsDll) if (NOT TcAdsDll_FOUND) - message(WARNING "Could NOT find TcAdsDll. TwinCat project targets will not be added.") + message(WARNING "Could NOT find TcAdsDll. TwinCAT router project targets will not be added.") endif () endif () # This list variable will contain all the targets that are created and need to be install. diff --git a/cmake/FindTcAdsDll.cmake b/cmake/FindTcAdsDll.cmake index ee44c0a0..e2f68e1f 100644 --- a/cmake/FindTcAdsDll.cmake +++ b/cmake/FindTcAdsDll.cmake @@ -16,15 +16,10 @@ if (NOT TcAdsDll_FIND_QUIETLY) message(STATUS "Looking for TcAdsDll (TwinCAT ADS-DLL)...") endif () -if (NOT WIN32) - message(WARNING "FindTcAdsDll.cmake only tested on WINDOWS") -endif () - if (WIN32) # Typical install locations on Windows set(_TcAdsDll_PATH "$ENV{SystemDrive}/TwinCAT/AdsApi/TcAdsDll") else () - # TODO: Linux not tested. Set additional known default locations to search. set(_TcAdsDll_PATH) endif () # Find the include headers @@ -34,7 +29,7 @@ find_path(TcAdsDll_INCLUDE_DIR PATH_SUFFIXES "Include" "include" ) # Find all related files base on the include files location. This is done -# assuming that the files are ordered as install by TwinCat. If they are +# assuming that the files are ordered as install by TwinCAT. If they are # in some other configuration this will not work. if (WIN32) cmake_path(GET TcAdsDll_INCLUDE_DIR PARENT_PATH TcAdsDll_ROOT_DIR) @@ -62,7 +57,6 @@ if (WIN32) NO_DEFAULT_PATH ) else () - # TODO: Linux not tested. We just try to look for the library by name. find_library(TcAdsDll_LIBRARY NAMES TcAdsDll ) From 0a442be36edcce18ad45f27afa4b18ec71dde779 Mon Sep 17 00:00:00 2001 From: juarezr Date: Mon, 6 Jul 2026 11:25:44 +0200 Subject: [PATCH 3/5] Add catch anything on AmsRouter - The variable exception 'e' was unsed in the catch leading to an unsed variable warning. - Instead of only catching std::exception class. Use catch-all (...) handler it catches any exception, regardless of its type. This guarantees that lock is released and events are always notify. The exception is still propagated at the end. --- AdsLib/standalone/AmsRouter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AdsLib/standalone/AmsRouter.cpp b/AdsLib/standalone/AmsRouter.cpp index 97c2b96e..db15552a 100644 --- a/AdsLib/standalone/AmsRouter.cpp +++ b/AdsLib/standalone/AmsRouter.cpp @@ -80,7 +80,7 @@ long AmsRouter::AddRoute(AmsNetId ams, const std::string &host) } return -1; - } catch (std::exception &e) { + } catch (...) { lock.lock(); connection_attempts.erase(ams); connection_attempt_events.notify_all(); From 25f15b5780329276c0f55d7ed4258d399796f11e Mon Sep 17 00:00:00 2001 From: juarezr Date: Mon, 6 Jul 2026 11:47:09 +0200 Subject: [PATCH 4/5] Use std::runtime_error instead of std::exception Fix clang-tidy ERR60-CPP rule "Exception objects must be nothrow copy constructable". std::exception is the abstract base class and does not have a constructor that accepts a string. Since you inherit from it the storage of the string message for what() needs to be allocated in the constructor of AdsException in this case using a std::string. Allocating a std::string can theoretically throw (e.g. bad_alloc). If your exception is copy more than once during stack unwinding you will not be able to catch anything. To solve this simply use std::runtime_error which comes with string constructors and noexcept copy constructors. Note here that errorCode should not be a public member of the exception as one also can theoretically, throw the const away and modify the value which is not something you want. However, this is leave "as is" for compatibility reasons. --- AdsLib/AdsException.h | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/AdsLib/AdsException.h b/AdsLib/AdsException.h index f9173c42..e1d0f059 100644 --- a/AdsLib/AdsException.h +++ b/AdsLib/AdsException.h @@ -8,25 +8,13 @@ #include #include -struct AdsException : std::exception { - AdsException(const long adsErrorCode) - : errorCode(adsErrorCode) - , m_Message("Ads operation failed with error code " + - std::to_string(adsErrorCode) + ".") +struct AdsException : std::runtime_error { + explicit AdsException(const long adsErrorCode) + : std::runtime_error("Ads operation failed with error code " + + std::to_string(adsErrorCode) + "."), + errorCode(adsErrorCode) { } - virtual ~AdsException() throw() - { - } - - virtual const char *what() const throw() - { - return m_Message.c_str(); - } - const long errorCode; - - protected: - const std::string m_Message; }; From c957544bdb3d72387801e4e64bc2da2b765833d1 Mon Sep 17 00:00:00 2001 From: juarezr Date: Mon, 6 Jul 2026 12:42:14 +0200 Subject: [PATCH 5/5] Fix wrong target when buiding shared lib - Wrong target TcAdsLib was name for target_compile_definitions when building a shared library. It should be AdsLib. --- AdsLib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AdsLib/CMakeLists.txt b/AdsLib/CMakeLists.txt index ddeff4af..cbfc533d 100644 --- a/AdsLib/CMakeLists.txt +++ b/AdsLib/CMakeLists.txt @@ -109,7 +109,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") endif () if (BUILD_SHARED_LIBS) - target_compile_definitions(TcAdsLib + target_compile_definitions(AdsLib PUBLIC BHF_ADS_EXPORT_C BHF_ADS_USE_TWINCAT_ORDER