1
okcdz 2021-01-04 13:33:30 +08:00
dll 是 C 写的代码,导出的 C 的接口
Python 解释器 C 写的,调用 dll 不是什么怪事,比如 Windows 下用 LoadLibraryA 函数,mac 用 dyld 方法。 有两种方法: 1. 直接用 FFI 调 C 接口的话,直接调用 C 写的函数,不用为 Python 写适配代码,很方便,但是有一定开销。 2. 也可以导出为 Python 的格式,但是要写一些胶水代码,其实内部也是一个 dll 而已。 |
2
RingSunKaiya OP Window 下 Python 调用 Dll 是 LoadLibrary(A),比如,是需要通过函数加载 Dll,才能使用,但现在的问题是 在 Python 脚本直接 import A,不用调用任何函数先加载 Dll 。
推测是先写的 Py 代码,然后转为 C 代码,最后打包成 Dll 详见 CSDN 上的一篇文章 https://blog.csdn.net/RingSunKaiya/article/details/112058851 |
3
dinjufen 2021-01-04 14:30:27 +08:00
之前写过一个 C++的 python binding,用的是 boost::python 相关的库,你只要遵循他的写法,就可以生成你说的这种 python 能直接 import 不需要其他操作的.pyd 文件( dll 也可)。
|
4
northisland 2021-01-04 15:12:27 +08:00
ctypes 大概是这样
from ctypes import CDLL foo = CDLL("./build/libxxxx.so") # 载入库 ret = foo.func(keypoints_p) # 调用 c++库接口 (数据绑定需要 3 句话) |
5
northisland 2021-01-04 15:15:50 +08:00
# 用 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 |
6
XIVN1987 2021-01-04 15:29:03 +08:00 2
虽然后缀名是 dll,,但文件内容可能是 pyd,,
毕竟后缀名可以随便改,,不能仅凭后缀名就断定文件内容 |
7
XIVN1987 2021-01-04 15:35:31 +08:00
@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,没有依赖、简化配置、更易使用,,下面这个帖子里有我的编译方法,可以看到非常简单: https://www.v2ex.com/t/740805 |
8
YaZuiBi 2021-01-04 15:43:51 +08:00
利用 C/C++创建 python 模块,里面用 LoadLibrary(动态链接库文件)加载动态链接库,然后打包成 xxx.pyd ,然后在 python 中 import xxx 就可以用。
|
9
ruanimal 2021-01-04 16:07:36 +08:00
@RingSunKaiya 和 linux 版 Python 直接 import so 是一个方法,用 c 写的代码 include python.h, 然后编译成动态库就可以了
|
10
ysc3839 2021-01-04 16:53:39 +08:00
估计是用 Python C API 写的 module,可以用纯 C 语言编写,也可以用 C++ 配合 pybind11 编写.
|
11
RingSunKaiya OP @YaZuiBi
Python 文件转 pyd 很好实现 |
12
RingSunKaiya OP @YaZuiBi 可以这样干?
|
13
RingSunKaiya OP @ruanimal 然后就可以直接 import 这个 dll 了
|
14
ruanimal 2021-01-04 17:31:41 +08:00
@RingSunKaiya 对,可以参考 swig,用的是同一个思路
|
15
YaZuiBi 2021-01-04 20:18:51 +08:00
@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 文件 |
16
RingSunKaiya OP 就是说.pyd 和.dll 以及.so 是没有太大的区别
|
17
linvaux 2021-01-04 22:04:37 +08:00 via iPhone
最近在做一个 sdk,加解密模块就是 py 编译成 so 和 pyd,然后导入的
|
18
no1xsyzy 2021-01-05 01:24:09 +08:00
@RingSunKaiya 我记得官网有句话,pyd 就是一个 dll,只不过改了个后缀名让它更容易被辨识,但并不影响它确实是个 dll
|
19
RingSunKaiya OP 3Q
|
20
RingSunKaiya OP 这样处理除了不让别人看到源码以外,还能提高速度吗?
|
21
RingSunKaiya OP @dinjufen 直接 import dll 的话 其实内部引用的是同名的 pyx,我把后缀 dll 改为 pyx,提示找不到模块,我把 dll 改为 pyd,就可以了,所以说应该是用 Python 代码转的 pyd,然后再改为 dll
|
22
RingSunKaiya OP |
23
ysc3839 2021-01-05 12:16:31 +08:00 via Android
@YaZuiBi 只是看 DLL 导出符号的话不需要安装 VS,可以使用 https://github.com/lucasg/Dependencies
|
24
RingSunKaiya OP |
25
RingSunKaiya OP 毕竟 py 转 pyd 很好实现
|