-
-
Notifications
You must be signed in to change notification settings - Fork 261
Possible Bug: load_library loses custom lib_location in error.py #572
Description
Hi,
while working on a project I encountered a strange behavior for an implementation of the snap7.client.Client(lib_location='/path/to/lib')
Setup
So in my current setup i just a Raspberry Pi to build a executable for Raspian and later transfer it to a "target" system.
Both Raspberry Pi Trixie 32bit OS.
I wanted to have a single executable to transfer so no global /usr/lib/libsnap7.so or similar. Thats why I choose to zip it in the executable and unzip snap7.so at runtime in /tmp/_MEI... folder. The dynamic link is gave my snap7.client.Client as param lib_location.
Enviroment:
- 2x RPi 4 with Trixie OS 32bit (build-system & target)
- executable form pyinstaller, with libsnap7.so zipped
- at runtime unzipped libsnap7.so in /tmp/_MEI... folder
- following call in my source code
s = snap7.client.Client(lib_locations=temp_location_snap7)
- use
pyinstallerto build project scptransferdist/appform build to target- execute
./app(no global, local or package libsnap7.so)
Expected behavior & problem
I was expecting that the custom lib_location i give snap7.client.Client will be used exclusively.
For a single successful connection this works fine. But as soon as you hit a connection error, the line 163 in error.py will call load_library with no params. So there will be no link to the snap7.so as there is neither a global, local or package installation of libsnap7.so.
Solution & change suggestion
My change suggestion for the common.py would be to "remember" the custom loaded "lib_location" in a global variable as the Client or Server will be called before the error handler.
# global variable to remember the loaded library
LIB_LOCATION = ''
@cache
def load_library(lib_location: Optional[str] = None) -> Snap7CliProtocol:
"""Loads the `snap7.dll` library.
Returns:
cdll: a ctypes cdll object with the snap7 shared library loaded.
"""
# check if there is a custom location set
# client load_libary() will called before any snap7.error is used
global LIB_LOCATION
if lib_location:
LIB_LOCATION = lib_location
if not lib_location:
lib_location = LIB_LOCATION or _find_in_package() or find_library("snap7") or _find_locally("snap7")
if not lib_location:
_raise_error()
return cast(Snap7CliProtocol, cdll.LoadLibrary(lib_location))
I know this might be a super edge rare edge case and not the pretties solution but this fix works for my case. Note i did not run any of the unittest as i did not got the test env to running in my python Raspberry Pi setup yet.