在没有imp.load_dynamic的情况下将DLL导入Python 3 [英] Importing DLL into Python 3 without imp.load_dynamic

查看:194
本文介绍了在没有imp.load_dynamic的情况下将DLL导入Python 3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试添加Windows对 Python的支持与目前仅Linux的Total Phase Aardvark 的接口。这是设备的包装器,其可用接口仅为.so(Linux)或.dll(Windows)封闭源二进制文件。但是,它是作为Python软件包(不确定是否是正确的术语)制成的,而不仅仅是将ctypes加载的标准C接口。

I am trying to add Windows support for Python Interface to Total Phase Aardvark that is currently Linux only . This is a wrapper for a device whose available interface is only a .so (Linux) or .dll (Windows) closed source binary. However, it was made as a Python package (not sure if that is the right term) rather than just standard C interface that your would load with ctypes.

在这个项目中,我们有一个ext文件夹,与导入脚本的级别相同,并具有用于Linux和Windows的32/64个库(由我添加):

In this project, we have an ext folder that is the same level as the script doing the importing, 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


导入问题


Linux实现使用:

Import Issues

Linux implementation uses:

from .ext.linux32 import aardvark as api

我最初测试在Python 2.7中添加Windows导入,但是无法使相对路径样式导入起作用。我唯一成功的方法如下:

I initially testing adding the windows import in Python 2.7 and was unable to get the relative path style import to work. The only method I was successful with is the following:

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都可用。

This seems ugly, but works fine with Python 2.7 and all of the api is available.

我切换到Python 3.4在那里进行测试,并发现不推荐使用imp。不仅如此,它看起来还不像imp从3.2版本开始在Python 3中具有load_dynamic。我无法在Python 3.4中找到使此DLL可用的方法。

I toggle over to Python 3.4 to test there and see that imp is deprecated. Not only that, it doesn't look like imp had load_dynamic in Python 3 from 3.2 on. I cannot find a way in Python 3.4 to make this DLL available.

在Python 2.7和Python 3.4中都失败

Fails in both Python 2.7 and Python 3.4

from .ext.win32 import aardvark as api


方法2


Python 2.7和Python 3.4均失败

Method 2

Fails in both Python 2.7 and 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中失败

Method 3

Works in Python 2.7, fails in 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中不会引发错误,但不是我要查找的内容

Method 4

Doesn't throw an error in Python 2.7 or Python 3.4, but not what I'm looking for

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

在Python 2.7中可以正常工作(imp.load_dynamic)导入, dir(api)给我:

With working (imp.load_dynamic) import in Python 2.7, dir(api) gives me:

['__ 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 , '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)给我:

ctypes import dir(api) gives me:

['_ 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兼容性。

I'm not sure what to try next. I'm fine working with my stuff in Python 2.7, but I'd really like to offer Python 3 compatibility.

推荐答案

I通过 importlib 在Python 3.6上导入外部库取得了一些成功。官方文档给出了此食谱以直接导入源文件:

I had some success with importing an external library on Python 3.6 through importlib. The official docs give this recipe to import a source file directly:

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#直接导入源文件文件

我将其修改为:

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上执行类似的操作:

You should then be able to do something like this on Python 3:

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

这篇关于在没有imp.load_dynamic的情况下将DLL导入Python 3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆