Python 中如何直接 import 某个 dll - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
RingSunKaiya

Python 中如何直接 import 某个 dll

  •  
  •   RingSunKaiya Jan 4, 2021 5864 views
    This topic created in 1941 days ago, the information mentioned may be changed or developed.
    情况:最近在看别人写的代码,发现该目录下只有 dll 和 py 文件,而 Py 文件的开头直接 Import 了这个 dll 文件,通过__file__方法,查看到导入包的路径和名称就是这个 py 文件同目录下的 dll 。
    问题:Python 可以直接 import 一个 dll 文件
    请问这个 dll 文件是如何生成的,是什么原理?
    是 Pythion 代码打包成 dll 还是用 C 写的 dll
    在网上查了以下资料 Python import 模块有四种方法
    1.使用 python 编写的.py 文件
    2.把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py 文件,该文件夹称之为包)
    3.使用 C 编写并链接到 python 解释器的内置模块
    4.已被编译为共享库或 DLL 的 C 或 C++扩展

    Python 引用 dll 是使用的 ctypes
    25 replies    2021-01-05 12:17:36 +08:00
    okcdz
        1
    okcdz  
       Jan 4, 2021
    dll 是 C 写的代码,导出的 C 的接口
    Python 解释器 C 写的,调用 dll 不是什么怪事,比如 Windows 下用 LoadLibraryA 函数,mac 用 dyld 方法。

    有两种方法:
    1. 直接用 FFI 调 C 接口的话,直接调用 C 写的函数,不用为 Python 写适配代码,很方便,但是有一定开销。
    2. 也可以导出为 Python 的格式,但是要写一些胶水代码,其实内部也是一个 dll 而已。
    RingSunKaiya
        2
    RingSunKaiya  
    OP
       Jan 4, 2021
    Window 下 Python 调用 Dl 是 LoadLibrary(A),比如,是需要通过函数加载 Dll,才能使用,但现在的问题是 在 Python 脚本直接 import A,不用调用任何函数先加载 Dll 。
    推测是先写的 Py 代码,然后转为 C 代码,最后打包成 Dll
    详见 CSDN 上的一篇文章
    https://blog.csdn.net/RingSunKaiya/article/details/112058851
    dinjufen
        3
    dinjufen  
       Jan 4, 2021
    之前写过一个 C++的 python binding,用的是 boost::python 相关的库,你只要遵循他的写法,就可以生成你说的这种 python 能直接 import 不需要其他操作的.pyd 文件( dll 也可)。
    northisland
        4
    northisland  
       Jan 4, 2021
    ctypes 大概是这样

    from ctypes import CDLL

    foo = CDLL("./build/libxxxx.so") # 载入库
    ret = foo.func(keypoints_p) # 调用 c++库接口 (数据绑定需要 3 句话)
    northisland
        5
    northisland  
       Jan 4, 2021
    # 用 numpy 搞定内存分配,传递给 c 形式的动态库
    c_float_p = ctypes.POINTER(ctypes.c_float) # 声明指针
    keypoints = np.ndarray(shape=(68, 2), dtype=np.float32) # numpy 对象,传回的关键点数组
    keypoints_p = keypoints.ctypes.data_as(c_float_p) # c++指针


    最高赞的回答,就是 ctypes 的套路
    https://stackoverflow.com/questions/5081875/ctypes-beginner
    XIVN1987
        6
    XIVN1987  
       Jan 4, 2021   2
    虽然后缀名是 dll,,但文件内容可能是 pyd,,

    毕竟后缀名可以随便改,,不能仅凭后缀名就断定文件内容
    XIVN1987
        7
    XIVN1987  
       Jan 4, 2021
    @dinjufen

    说到 boost::python,,那不如试试它的一个轻量级复制品,,

    pybind11 is a lightweight header-only library that exposes C++ types in Python and vice versa, mainly to create Python bindings of existing C++ code. Its goals and syntax are similar to the excellent Boost.Python library by David Abrahams: to minimize boilerplate code in traditional extension modules by inferring type information using compile-time introspection.

    header-only,没有依赖、简化配置、更易使用,,下面这个帖子里有我的编译方法,可以看到非常简单:

    t/740805
    YaZuiBi
        8
    YaZuiBi  
       Jan 4, 2021
    利用 C/C++创建 python 模块,里面用 LoadLibrary(动态链接库文件)加载动态链接库,然后打包成 xxx.pyd ,然后在 python 中 import xxx 就可以用。
    ruanimal
        9
    ruanimal  
       Jan 4, 2021
    @RingSunKaiya 和 linux 版 Python 直接 import so 是一个方法,用 c 写的代码 include python.h, 然后编译成动态库就可以了
    ysc3839
        10
    ysc3839  
       Jan 4, 2021
    估计是用 Python C API 写的 module,可以用纯 C 语言编写,也可以用 C++ 配合 pybind11 编写.
    RingSunKaiya
        11
    RingSunKaiya  
    OP
       Jan 4, 2021 via Android
    @YaZuiBi
    Python 文件转 pyd 很好实现
    RingSunKaiya
        12
    RingSunKaiya  
    OP
       Jan 4, 2021 via Android
    @YaZuiBi 可以这样干?
    RingSunKaiya
        13
    RingSunKaiya  
    OP
       Jan 4, 2021 via Android
    @ruanimal 然后就可以直接 import 这个 dll 了
    ruanimal
        14
    ruanimal  
       Jan 4, 2021
    @RingSunKaiya 对,可以参考 swig,用的是同一个思路
    YaZuiBi
        15
    YaZuiBi  
       Jan 4, 2021
    @RingSunKaiya 可以的,但是语法需要能够转成 Python 模块才行。

    https://blog.csdn.net/pengyancai/article/details/54587955?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control

    另外你这里的.dll 文件,要是装了 VS,用
    dumpbin.exe -exports xxx.dll 看看链接库的对外接口,防止这个文件不是真正的 dll 文件
    RingSunKaiya
        16
    RingSunKaiya  
    OP
       Jan 4, 2021 via Android
    就是说.pyd 和.dll 以及.so 是没有太大的区别
    linvaux
        17
    linvaux  
       Jan 4, 2021 via iPhone
    最近在做一个 sdk,加解密模块就是 py 编译成 so 和 pyd,然后导入的
    no1xsyzy
        18
    no1xsyzy  
       Jan 5, 2021
    @RingSunKaiya 我记得官网有句话,pyd 就是一个 dll,只不过改了个后缀名让它更容易被辨识,但并不影响它确实是个 dll
    RingSunKaiya
        19
    RingSunKaiya  
    OP
       Jan 5, 2021 via Android
    3Q
    RingSunKaiya
        20
    RingSunKaiya  
    OP
       Jan 5, 2021 via Android
    这样处理除了不让别人看到源码以外,还能提高速度吗?
    RingSunKaiya
        21
    RingSunKaiya  
    OP
       Jan 5, 2021 via Android
    @dinjufen 直接 import dll 的话 其实内部引用的是同名的 pyx,我把后缀 dll 改为 pyx,提示找不到模块,我把 dll 改为 pyd,就可以了,所以说应该是用 Python 代码转的 pyd,然后再改为 dll
    RingSunKaiya
        22
    RingSunKaiya  
    OP
       Jan 5, 2021 via Android
    @dinjufen 直接 import dll 的话 其实内部引用的是同名的 pyx,我把后缀 dll 改为 pyx,提示找不到模块,我把 dll 改为 pyd,就可以了,所以说应该是用 Python 代码转的 pyd,然后再改为 dll
    @XIVN1987
    ysc3839
        23
    ysc3839  
       Jan 5, 2021 via Android
    @YaZuiBi 只是看 DLL 导出符号的话不需要安装 VS,可以使用 https://github.com/lucasg/Dependencies
    RingSunKaiya
        24
    RingSunKaiya  
    OP
       Jan 5, 2021 via Android
    @dinjufen 直接 import dll 的话 其实内部引用的是同名的 pyx,我把后缀 dll 改为 pyx,提示找不到模块,我把 dll 改为 pyd,就可以了,所以说应该是用 Python 代码转的 pyd,然后再改为 dll
    @YaZuiBi
    RingSunKaiya
        25
    RingSunKaiya  
    OP
       Jan 5, 2021 via Android
    毕竟 py 转 pyd 很好实现
    About     Help     Advertise     Blog     API     FAQ     Solana     3237 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 58ms UTC 13:20 PVG 21:20 LAX 06:20 JFK 09:20
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86