Skip to content

Commit

Permalink
Introduce use_tmpcpy parameter to Library constructor (#166) (#172)
Browse files Browse the repository at this point in the history
This patch introduces a parameter to the constructor for the `JLink` instance,
as well as the `Library` instance to prevent the internal behaviour of copying
the library to allow for multiple debuggers to be used at the same time in
earlier versions of the SDK.
  • Loading branch information
chanqueo committed May 1, 2023
1 parent 34083a2 commit 6313307
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 16 deletions.
5 changes: 3 additions & 2 deletions pylink/jlink.py
Expand Up @@ -247,7 +247,7 @@ def wrapper(self, *args, **kwargs):
return _interface_required

def __init__(self, lib=None, log=None, detailed_log=None, error=None, warn=None, unsecure_hook=None,
serial_no=None, ip_addr=None, open_tunnel=False):
serial_no=None, ip_addr=None, open_tunnel=False, use_tmpcpy=True):
"""Initializes the J-Link interface object.
Note:
Expand Down Expand Up @@ -279,6 +279,7 @@ def __init__(self, lib=None, log=None, detailed_log=None, error=None, warn=None,
of ``open`` method.
If ``None``, the driver will not be opened automatically
(however, it is still closed when exiting the context manager).
use_tmpcpy (bool): True to load a temporary copy of J-Link DLL
Returns:
``None``
Expand All @@ -289,7 +290,7 @@ def __init__(self, lib=None, log=None, detailed_log=None, error=None, warn=None,
self._initialized = False

if lib is None:
lib = library.Library()
lib = library.Library(use_tmpcpy=use_tmpcpy)

if lib.dll() is None:
raise TypeError('Expected to be given a valid DLL.')
Expand Down
35 changes: 21 additions & 14 deletions pylink/library.py
Expand Up @@ -260,7 +260,7 @@ def find_library_darwin(cls):
if f.startswith(dll):
yield os.path.join(dir_path, f)

def __init__(self, dllpath=None):
def __init__(self, dllpath=None, use_tmpcpy=True):
"""Initializes an instance of a ``Library``.
Loads the default J-Link DLL if ``dllpath`` is ``None``, otherwise
Expand All @@ -269,6 +269,7 @@ def __init__(self, dllpath=None):
Args:
self (Library): the ``Library`` instance
dllpath (str): the DLL to load into the library
use_tmpcpy (bool): True to load a temporary copy of J-Link DLL
Returns:
``None``
Expand All @@ -278,6 +279,7 @@ def __init__(self, dllpath=None):
self._path = None
self._windows = sys.platform.startswith('win')
self._cygwin = sys.platform.startswith('cygwin')
self._use_tmpcpy = use_tmpcpy
self._temp = None

if self._windows or self._cygwin:
Expand Down Expand Up @@ -387,28 +389,33 @@ def load(self, path=None):
else:
suffix = '.so'

# Copy the J-Link DLL to a temporary file. This will be cleaned up the
# next time we load a DLL using this library or if this library is
# cleaned up.
tf = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
with open(tf.name, 'wb') as outputfile:
with open(self._path, 'rb') as inputfile:
outputfile.write(inputfile.read())
lib_path = self._path

# This is needed to work around a WindowsError where the file is not
# being properly cleaned up after exiting the with statement.
tf.close()
if self._use_tmpcpy:
# Copy the J-Link DLL to a temporary file. This will be cleaned up the
# next time we load a DLL using this library or if this library is
# cleaned up.
tf = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
with open(tf.name, 'wb') as outputfile:
with open(self._path, 'rb') as inputfile:
outputfile.write(inputfile.read())

self._temp = tf
self._lib = ctypes.cdll.LoadLibrary(tf.name)
# This is needed to work around a WindowsError where the file is not
# being properly cleaned up after exiting the with statement.
tf.close()

lib_path = tf.name
self._temp = tf

self._lib = ctypes.cdll.LoadLibrary(lib_path)

if self._windows:
# The J-Link library uses a mix of __cdecl and __stdcall function
# calls. While this is fine on a nix platform or in cygwin, this
# causes issues with Windows, where it expects the __stdcall
# methods to follow the standard calling convention. As a result,
# we have to convert them to windows function calls.
self._winlib = ctypes.windll.LoadLibrary(tf.name)
self._winlib = ctypes.windll.LoadLibrary(lib_path)
for stdcall in self._standard_calls_:
if hasattr(self._winlib, stdcall):
# Backwards compatibility. Some methods do not exist on
Expand Down

0 comments on commit 6313307

Please sign in to comment.