知行编程网知行编程网  2022-08-17 18:30 知行编程网 隐藏边栏  308 
文章评分 1 次,平均分 5.0
导语: 本文主要介绍了关于python怎么生成dll的相关知识,包括python打包dll,以及python调用labview这些编程知识,希望对大家有参考作用。

python如何生成dll


使用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>
}
 
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。具体步骤如下:

(1) virtualenv envpack #新建环境,python包依赖比较复杂,新建环境可以减少最后引入包;

(2)cd envpack # 进入目录;

(3)#将run.py复制到该目录下,run.py运行所需的包与最终dll所需的包相同;

(4)Scripts\activate # 激活并切换到virtualenv环境;

(5)pip install pyinstaller # 安装打包工具pyinstaller;

(6)pip install numpy # 安装numpy等脚本需要的库,查看你的import;

(7)pyinstaller run.py # 打包命令;

(8)Scripts\deactivate # 打包成功后,使用命令取消激活环境;

(9) 需要打包的文件在envpack\dist中,包括很多.dll和.pyd文件,可以和dll一起发布。

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享