Import DLL in Python 3 without imp.load_dynamic

purpose

I am trying to add Windows support for the Python Interface for Total Phase Aardvark , which is currently only Linux. This is a shell for a device whose accessible interface is only a binary file with the extension .so (Linux) or .dll (Windows) with closed source code. However, it was made as a Python package (not sure if this is the correct term), and not just the standard C interface that will be loaded using ctypes.

File structure

In this project, we have an ext folder, which at the same level as the script does the import, with 32/64 libraries for Linux and Windows (added by me):

pyaardvark.py (file doing imports)
ext
  linux32
    __init.py__ (empty)
    aardvark.so
  linux 64
    __init.py__ (empty)
    aardvark.so
  win32
    __init.py__ (empty)
    aardvark.dll
  win64
    __init.py__ (empty)
    aardvark.dll

Import issues

The Linux implementation uses:

from .ext.linux32 import aardvark as api

Windows Python 2.7 . , , :

import imp
import os
cur_path = os.path.dirname(__file__)
api = imp.load_dynamic('aardvark', os.path.join(cur_path, 'ext', 'win32', 'aardvark.dll'))

, Python 2.7 api .

Python 3.4, , imp . , , imp load_dynamic Python 3 3.2 . Python 3.4, DLL .

1

Python 2.7, Python 3.4

from .ext.win32 import aardvark as api

2

Python 2.7, Python 3.4

import importlib
import os
cur_path = os.path.dirname(__file__)
api = importlib.import_module('aardvark', os.path.join(cur_path, 'ext', 'win32', 'aardvark.dll'))

3

Python 2.7, Python 3.4

import imp
import os
cur_path = os.path.dirname(__file__)
api = imp.load_dynamic('aardvark', os.path.join(cur_path, 'ext', 'win32', 'aardvark.dll'))

4

Python 2.7 Python 3.4, ,

import os
cur_path = os.path.dirname(__file__)
from ctypes import cdll
api = cdll.LoadLibrary(os.path.join(cur_path, 'ext', 'win32', 'aardvark.dll'))

(imp.load_dynamic) Python 2.7, dir(api) :

['__doc__', '__file__', '__name__', '__package__', 'py_aa_async_poll', 'py_aa_close', 'py_aa_configure', 'py_aa_features', 'py_aa_find_devices', 'py_aa_find_devices_ext', 'py_aa_gpio_change', 'py_aa_gpio_direction', 'py_aa_gpio_get', 'py_aa_gpio_pullup', 'py_aa_gpio_set', 'py_aa_i2c_bitrate', 'py_aa_i2c_bus_timeout', 'py_aa_i2c_free_bus', 'py_aa_i2c_monitor_disable', 'py_aa_i2c_monitor_enable', 'py_aa_i2c_monitor_read', 'py_aa_i2c_pullup', 'py_aa_i2c_read', 'py_aa_i2c_read_ext', 'py_aa_i2c_slave_disable', 'py_aa_i2c_slave_enable', 'py_aa_i2c_slave_read', 'py_aa_i2c_slave_read_ext', 'py_aa_i2c_slave_set_response', 'py_aa_i2c_slave_write_stats', 'py_aa_i2c_slave_write_stats_ext', 'py_aa_i2c_write', 'py_aa_i2c_write_ext', 'py_aa_i2c_write_read', 'py_aa_log', 'py_aa_open', 'py_aa_open_ext', 'py_aa_port', 'py_aa_sleep_ms', 'py_aa_spi_bitrate', 'py_aa_spi_configure', 'py_aa_spi_master_ss_polarity', 'py_aa_spi_slave_disable', 'py_aa_spi_slave_enable', 'py_aa_spi_slave_read', 'py_aa_spi_slave_set_response', 'py_aa_spi_write', 'py_aa_status_string', 'py_aa_target_power', 'py_aa_unique_id', 'py_aa_version', 'py_version']

ctypes import dir(api) :

['_FuncPtr', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_func_flags_', '_func_restype_', '_handle', '_name']

, . Python 2.7, Python 3.

+4
1

Python 3.6 importlib. :

import importlib.util
import sys

# For illustrative purposes.
import tokenize
file_path = tokenize.__file__
module_name = tokenize.__name__

spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
# Optional; only necessary if you want to be able to import the module
# by name later.
sys.modules[module_name] = module

(https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly)

:

import importlib.util

def load_dynamic(module, path):
    spec = importlib.util.spec_from_file_location(module, path)
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return mod

- Python 3:

load_dynamic('aardvark', os.path.join(cur_path, 'ext', 'win32', 'aardvark.dll'))
0

Source: https://habr.com/ru/post/1544181/


All Articles