Skip to content

Possible Bug: load_library loses custom lib_location in error.py #572

@AndreasScharf

Description

@AndreasScharf

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)
  1. use pyinstaller to build project
  2. scp transfer dist/app form build to target
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions