使用python创建生成动态链接库dll
如今,随着深度学习的发展,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)));
} 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的更多相关文章
- 创建一个动态链接库 (DLL),使用VS2010
在本演练中,您将创建一个动态链接库 (DLL),其中包含可供其他应用程序使用的有用例程.使用 DLL 是一种重用代码的绝佳方式.您不必在自己创建的每个程序中重新实现这些例程,而只需对这些例程编写一次, ...
- MinGW gcc 生成动态链接库 dll 的一些问题汇总 (补充)
我以前写过一个小短文,介绍MinGW gcc 生成动态链接库 dll 的一些问题.当时写的并不全面.近期又遇到写新的问题.这里记录一下,做个补充. 通常情况下,dll 中的函数假设採用 _stdcal ...
- dll = MinGW gcc 生成动态链接库 dll 的一些问题汇总
MinGW gcc 生成动态链接库 dll 的一些问题汇总 https://blog.csdn.net/liyuanbhu/article/details/42612365 网络上关于用 MinGW ...
- MinGW gcc 生成动态链接库 dll 的一些问题汇总(由浅入深,很详细)
网络上关于用 MinGW gcc 生成动态链接库的文章很多.介绍的方法也都略有不同.这次我在一个项目上刚好需要用到,所以就花了点时间将网上介绍的各种方法都实验了一遍.另外,还根据自己的理解试验了些网上 ...
- 动态链接库DLL的创建生成及调用
一.背景 最近在做CANTOUSB底层驱动的调用,是调用别人已经封装好的库,看不到别人写的源程序.程序中调用的是隐式调用即 x.h+x.lib+x.dll,其中DLL即是动态链接库(Dynamic L ...
- vs2010创建和使用动态链接库(dll)
本文将创建一个简单的动态链接库,并编写一个应用台控制程序使用该动态链接库,并提出了与实现相关的几个问题,供初学者交流. 本文包含以下内容: 创建动态链接库项目 向动态链接库添加类 创建引用动态链接库的 ...
- MFC创建动态链接库DLL并调用方法详解
实例一: 1.创建一个动态链接库工程,如login_dll. 2.在原工程头文件或者新建头文件如showdlg.h定义动态链接库的导出函数,代码如下: #include "stdafx.h& ...
- vs2010 C++创建和使用动态链接库(dll)
一.用C++创建动态链接库项目: 1.打开Microsoft Visual Studio 2010,选择File->New->Project. 2.在NewProject中选择Inst ...
- C# 创建和引入动态链接库dll文件
一.创建动态链接库dll文件 新建 -> 项目->类库 名称为:dlltest 添加函数:消息框弹出消息 using System.Collections.Generic; using S ...
随机推荐
- Java String 面试题以及答案
String是最常使用的Java类之一,整理的了一些重要的String知识分享给大家. 作为一个Java新手程序员,对String进行更深入的了解很有必要.如果你是有几年Java开发经验,可以根据目录 ...
- C/C++ 笔试题一
摘自 网络上的 笔试题,据说是华为的,考察的内容还算全面,也很细致: 答案 疏略 检查了下,应该没有什么大问题,但是 还是那句话,尽信之不如无,所以还是要自己思考 1.static有什么用途?(请至少 ...
- DotNet Core Console 程序使用NLog
参考:https://github.com/NLog/NLog/wiki/Tutorial 步骤: 1. 使用Nuget安装NLog.Extensions.Logging Install-Packag ...
- 【工作】to-do-list
当你不确定的时候,你就把你所在的工作做好,所在的你不愿意的行业做好,所谓的自由选择,它本身不自由的,不自由过程当中,如何你把它做好,就做人生的一个经历,人生的一个积累.-- 王石 TODO
- [转载] FFMPEG结构体分析:AVFrame
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrameFFMPEG结构体分析:AVFormatContextFFMPEG结构体分析:AVCodecContext ...
- 【转】C# Socket编程(1)基本的术语和概念
[转自:http://www.cnblogs.com/IPrograming/archive/2012/10/10/2718371.html#Protocol] 计算机程序能够相互联网,相互通讯,这使 ...
- ACM学习历程—TopCoder SRM691 Div2
这是我的第一次打TC,感觉打的一般般吧.不过TC的题目确实挺有意思的. 由于是用客户端打的,所以就不发题目地址了. 300分的题: 这题大意是有一段序列只包含+和数字0~9. 一段序列的操作是,从头扫 ...
- 洛谷 P3225 [HNOI2012]矿场搭建
传送门 题目大意:建设几个出口,使得图上无论哪个点被破坏,都可以与出口联通. 题解:tarjian求割点 首先出口不能建在割点上,找出割点,图就被分成了几个联通块. 每个联通块,建出口.如果割点数为0 ...
- fn project 运行时配置选项
Env Variables Description Default values DB_URL The database URL to use in URL format. SeeDatabases ...
- 使用BasicDataSource连接池连接oracle数据库报错ORA-12505
先看连接池配置: <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" ...