使用python创建生成动态链接库dll的方法


Posted in Python onMay 09, 2020

如今,随着深度学习的发展,python已经成为了深度学习研究中第一语言。绝大部分的深度学习工具包都有python的版本,很多重要算法都有python版本的实现。为了将这些算法应用到具体工程中,这些工具包也提供了不同类型的接口。

动态链接库(.dll,.so)是系统开发中一种非常重要的跨语言协作方式。把python语言写成的算法编译成动态库,能够提供给其他语言调用,这能够在很大程度上提高算法的开发效率。

但是,虽然python可以调用其他语言生成的动态库,python作为一种脚本语言,本身是不能直接编译生成动态库的。为了生成动态库,我们借助cython,将python脚本变成c语言文件。具体过程,我们通过一个简单的例子来解释。

def str_add(str1,str2): 
    return int(str1) + int(str2)

这个代码,将两个数字组成的字符串转化成数字,并求和。我们把这个代码保存成run.py备用。根据cython的语法,我们给出cython版本的函数:

cdef public str_add(str1,str2):
     return int(str1) + int(str2)

和前面python版本的相比,cdef替换了def,并加了public关键字,表示这个函数要导出。将这个代码保存成pyx文件,比如run.pyx。

接下来,我们执行如下命令,把这个代码变成c语言版本:

cython run.pyx

这时,目录下面生出来run.h和run.c两个文件。这个两个文件通过调用python的C-API实现了run.py代码的功能。

接下来,我们编写动态库的主文件dllmain.c:

#include <Python.h>
#include <Windows.h>
#include "run.h"
 
extern __declspec(dllexport) int __stdcall _str_add(const char * a, const char * b) {
  return PyLong_AsLong(str_add(PyUnicode_FromString(a),PyUnicode_FromString(b)));<br data-filtered="filtered">
}
 
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved) {
  switch( fdwReason ) {
    case DLL_PROCESS_ATTACH:
      Py_Initialize();
      PyInit_run(); #dll初始化的时候调用,这是python3的写法,python2改成,initrun()。参见生成的run.h
      break;
    case DLL_PROCESS_DETACH:
      Py_Finalize();
      break;
  }
  return TRUE;
}

该文件定义了导出函数_str_add。在python中,所有数据都以pyobject进行存储。这个函数通过PyUnicode_FromString,将两个字符串变成python对象类型,并调用run.h里面的函数str_add求和,并把结果通过PyLong_AsLong函数从python对象,变成整形数字。

我们可以通过如下命令,将这个代码编译生成dll:

cl /LD dllmain.c run.c -IC:\python36\include C:\python36\libs\python36.lib

这里python的路径,根据不同电脑python的安装位置,做相应调整。

生成的dll,我们写个简单调用,测试一下:

#include "stdio.h"
#include "stdlib.h"
extern __declspec(dllexport) int __stdcall _str_add(const char * a, const char * b);
 
#pragma comment(lib,"dllmain.lib")
 
int main()
{
 printf("%d \n", _str_add("123","456"));
 return 0;
}

输出结果: 579,正好等于123+456。

通过以上步骤,我们已经能够把python代码实现的功能,封装成动态库。然而,这个动态库无法在没有安装python的机器上面运行。事实上,python代码,通常需要很多依赖包才能运行。而且,每段代码需要的依赖包是不一样的。为了查找这些包,我们采用另外一个工具pyinstaller。具体步骤简介如下:

virtualenv envpack # 创建新的环境,python包依赖比较复杂,创建新环境可以减少最终引入的包
cd envpack # 进入目录
#复制run.py到这个目录,run.py运行需要的包,和最终dll需要的包是一样的
Scripts\activate # 激活并切换到virtualenv环境
pip install pyinstaller # 安装打包工具pyinstaller
pip install numpy # 安装numpy等脚本需要的库,查看你的import
pyinstaller run.py # 打包命令
Scripts\deactivate # 打包成功后,使用命令取消激活环境
需要打包的文件在envpack\dist, 包括很多.dll和.pyd文件,把这些文件和dll一起发布即可。

总结

到此这篇关于使用python创建生成动态链接库dll的方法的文章就介绍到这了,更多相关python动态链接库dll内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python获取当前时间的方法
Jan 14 Python
Python安装Imaging报错:The _imaging C module is not installed问题解决方法
Aug 22 Python
Python实现的数据结构与算法之队列详解
Apr 22 Python
Scrapy框架CrawlSpiders的介绍以及使用详解
Nov 29 Python
解决pandas中读取中文名称的csv文件报错的问题
Jul 04 Python
PyTorch读取Cifar数据集并显示图片的实例讲解
Jul 27 Python
3分钟学会一个Python小技巧
Nov 23 Python
TensorFlow加载模型时出错的解决方式
Feb 06 Python
TFRecord文件查看包含的所有Features代码
Feb 17 Python
django queryset 去重 .distinct()说明
May 19 Python
Python如何绘制日历图和热力图
Aug 07 Python
python缺失值填充方法示例代码
Dec 24 Python
浅析python 动态库m.so.1.0错误问题
May 09 #Python
Python实现常见的几种加密算法(MD5,SHA-1,HMAC,DES/AES,RSA和ECC)
May 09 #Python
Python发送邮件封装实现过程详解
May 09 #Python
pycharm第三方库安装失败的问题及解决经验分享
May 09 #Python
pycharm无法安装第三方库的问题及解决方法以scrapy为例(图解)
May 09 #Python
pip安装提示Twisted错误问题(Python3.6.4安装Twisted错误)
May 09 #Python
Python接口测试数据库封装实现原理
May 09 #Python
You might like
PHP教程 基本语法
2009/10/23 PHP
PHP模拟登陆163邮箱发邮件及获取通讯录列表的方法
2015/03/07 PHP
Laravel如何创建服务器提供者实例代码
2019/04/15 PHP
Thinkphp5.0 框架实现控制器向视图view赋值及视图view取值操作示例
2019/10/12 PHP
jQuery powerFloat万能浮动层下拉层插件使用介绍
2010/12/27 Javascript
jquery.tmpl JQuery模板插件
2011/10/10 Javascript
extjs tabpanel限制选项卡数量实现思路及代码
2013/04/02 Javascript
在jquery中combobox多选的不兼容问题总结
2013/12/24 Javascript
javascript与有限状态机详解
2014/05/08 Javascript
妙用Bootstrap的 popover插件实现校验表单提示功能
2016/08/29 Javascript
什么是JavaScript注入攻击?
2016/09/14 Javascript
jQuery.Validate表单验证插件的使用示例详解
2017/01/04 Javascript
详解基于Koa2开发微信二维码扫码支付相关流程
2018/05/16 Javascript
使用JavaScript保存文本文件到本地的两种方法
2019/01/22 Javascript
vue路由导航守卫和请求拦截以及基于node的token认证的方法
2019/04/07 Javascript
微信小程序 函数防抖 解决重复点击消耗性能问题实现代码
2019/09/12 Javascript
vue项目启动出现cannot GET /服务错误的解决方法
2020/04/26 Javascript
vue内置组件component--通过is属性动态渲染组件操作
2020/07/28 Javascript
Javascript基于OOP实实现探测器功能代码实例
2020/08/26 Javascript
vue.js 输入框输入值自动过滤特殊字符替换中问标点操作
2020/08/31 Javascript
vue实现购物车的小练习
2020/12/21 Vue.js
Python实现简单的文本相似度分析操作详解
2018/06/16 Python
python实现nao机器人身体躯干和腿部动作操作
2019/04/29 Python
Python Tornado之跨域请求与Options请求方式
2020/03/28 Python
使用Nibabel库对nii格式图像的读写操作
2020/07/01 Python
通过实例解析Python文件操作实现步骤
2020/09/21 Python
应届大学毕业生找工作的求职信范文
2013/11/29 职场文书
好军嫂事迹材料
2014/01/15 职场文书
运动会广播稿150字
2014/02/19 职场文书
月度优秀员工获奖感言
2014/08/16 职场文书
2014年学校财务工作总结
2014/12/06 职场文书
银行实习推荐信
2015/03/27 职场文书
办公用品质量保证书
2015/05/11 职场文书
教你怎么用Python操作MySql数据库
2021/05/31 Python
游戏《我的世界》澄清Xbox版暂无计划加入光追
2022/04/03 其他游戏
python在package下继续嵌套一个package
2022/04/14 Python