From 9a22c052d984ff0888576bb699a27fc4173a44d1 Mon Sep 17 00:00:00 2001 From: David Van Arnem Date: Wed, 16 Apr 2025 16:57:08 -0600 Subject: [PATCH] Rework loading vxlapi/vxlapi64.dll so locations added with os.add_dll_directory() are searched In Python 3.8, DLL loading changed, and the recommended way to add arbitrary directories to the search locations is with os.add_dll_directory(), see https://docs.python.org/3/library/os.html#os.add_dll_directory can/interfaces/vector/xldriver.py used ctypes.util.find_library() to first get a path to the vxlapi/vxlapi64 for the DLLs; if a path was found, the DLL was loaded with ctypes.windll.LoadLibrary(), if not, a FileNotFoundError exception was manually raised. find_library() only searches paths in os.environ['PATH'], which does not include directories added with os.add_dll_directory(), so find_library() fails if the vxlapi DLLs are located in an arbitrary (non-standard) directory, whether or not the directory was first added with add_dll_directory(). LoadLibrary() raises a FileNotFoundError if the DLL cannot be located, and it will look in the standard locations and arbitrary locations added with add_dll_directory(). So, rather than trying to find the DLL first with find_library(), simply wrap the LoadLibrary() call in a try/except block and raise any exceptions. This has two benefits: first, it allows the vxlapi DLLs to be located in an arbitrary directory that can be added in an end-user script with os.add_dll_directory(); second, it catches other exceptions raised by LoadLibrary(). --- can/interfaces/vector/xldriver.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/can/interfaces/vector/xldriver.py b/can/interfaces/vector/xldriver.py index faed23b36..555b941a6 100644 --- a/can/interfaces/vector/xldriver.py +++ b/can/interfaces/vector/xldriver.py @@ -17,10 +17,11 @@ # Load Windows DLL DLL_NAME = "vxlapi64" if platform.architecture()[0] == "64bit" else "vxlapi" -if dll_path := find_library(DLL_NAME): - _xlapi_dll = ctypes.windll.LoadLibrary(dll_path) -else: - raise FileNotFoundError(f"Vector XL library not found: {DLL_NAME}") +# attempt to load Vector XL Driver DLL in a way that accomodates DLL directories added with os.add_dll_directory() +try: + _xlapi_dll = ctypes.windll.LoadLibrary(DLL_NAME) +except: + raise # ctypes wrapping for API functions xlGetErrorString = _xlapi_dll.xlGetErrorString