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

 更新时间:2020年05月09日 14:15:53   作者:xueliangliu  
这篇文章主要介绍了使用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)));<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 内置函数速查表一览

    这篇文章主要介绍了Python 内置函数速查表,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Python Word文件自动化实战之简历筛选

    Python Word文件自动化实战之简历筛选

    本文将利用Python自动化做一个具有实操性的小练习,即通过读取简历来筛选出符合招聘条件的简历。文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-05-05
  • 详解Python操作Excel之openpyxl

    详解Python操作Excel之openpyxl

    这篇文章主要为大家介绍了Python操作Excel的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • NumPy 数组使用大全

    NumPy 数组使用大全

    这篇文章主要介绍了NumPy 数组使用大全,在本教程中,你将学习如何在 NumPy 数组上以多种方式添加、删除、排序和操作元素。 文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • python如何输出反斜杠

    python如何输出反斜杠

    在本篇内容中小编给大家整理了一篇关于python怎么输出反斜杠的相关基础文章,有兴趣的朋友们可以学习参考下。
    2020-06-06
  • Python简单实现子网掩码转换的方法

    Python简单实现子网掩码转换的方法

    这篇文章主要介绍了Python简单实现子网掩码转换的方法,涉及Python字符串相关操作技巧,需要的朋友可以参考下
    2016-04-04
  • python 实现屏幕录制示例

    python 实现屏幕录制示例

    今天小编就为大家分享一篇python 实现屏幕录制示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • python数据结构之链表的实例讲解

    python数据结构之链表的实例讲解

    下面小编就为大家带来一篇python数据结构之链表的实例讲解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Python中的数字类型与转换技巧示例讲解

    Python中的数字类型与转换技巧示例讲解

    这篇文章主要为大家介绍了Python中的数字类型与转换技巧示例讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • itchat和matplotlib的结合使用爬取微信信息的实例

    itchat和matplotlib的结合使用爬取微信信息的实例

    下面小编就为大家带来一篇itchat和matplotlib的结合使用爬取微信信息的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08

最新评论