【windows】Python文件打包成dll文件及遇见的问题

news2024/11/25 18:57:32

最近需要将py文件转为dll,特此记录。
操作步骤来自于:将Python文件发布成DLL并调用

写一个py文件

文件名:test_numpy.py

import numpy as np
 
def func(my_list1, my_list2):
    list_np1 = np.array(my_list1)
    list_np2 = np.array(my_list2)
    return list(list_np1 + list_np2)

测试确认能运行成功。

生成DLL

vs2017新建dll项目:
项目名:Dll1
在这里插入图片描述
创建后,可以看到资源管理器,只需要用到pch.h和pch.cpp。
在这里插入图片描述

配置项目属性
在菜单里”调试“-》”Dll1属性“
在这里插入图片描述
分别添加python.exe所在的目录下的include文件夹路径和libs文件夹。

在这里插入图片描述
在这里插入图片描述
添加python依赖项:
在这里插入图片描述
注意要与版本对应,如果不知道版本可以在python中输入

import sys
print(sys.version)

查看版本。

在pch.h输入:

#ifndef PCH_H
#define PCH_H

// 添加要在此处预编译的标头
#include "framework.h"


extern "C" _declspec(dllexport) long* listAdd(int a[], int b[], int n); // 将两个数组相加,并返回新数组

#endif //PCH_H

在pch.cpp输入:

// pch.cpp: 与预编译标头对应的源文件

#include "pch.h"

// 当使用预编译的头时,需要使用此源文件,编译才能成功。
// pch.cpp: 与预编译标头对应的源文件

#include <Python.h>
#include <iostream>

using namespace std;

// 当使用预编译的头时,需要使用此源文件,编译才能成功。

long* listAdd(int a[], int b[], int n)
{
	Py_SetPythonHome(L"C:/Users/AppData/Local/Programs/Python/Python310-32/"); //这里地址一定要写对啊!
	// 这里要写和在设置属性时的python.exe一样的路径,不然会出现错误

	//***python调用***//
	//初始化python模块
	Py_Initialize();
	// 检查初始化是否成功  
	if (!Py_IsInitialized())
	{
		cout << "初始化失败" << endl;
		Py_Finalize();
	}
	PyObject* pModule;
	PyObject* pFunc = NULL;
	PyObject* pArg = NULL;
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('./')");//设置python模块,搜寻位置,文件放在.cpp文件一起


	pModule = PyImport_ImportModule("test_numpy");//Python文件名     
	if (!pModule) {
		cout << "py文件导入失败" << endl;
		Py_Finalize();
		return NULL;
	}
	else {
		pFunc = PyObject_GetAttrString(pModule, "func");//Python文件中的函数名  
		if (!pFunc) {
			cout << "函数导入失败" << endl;
			Py_Finalize();
			return NULL;
		}

		PyObject *pyParamsA = PyList_New(n), *pyParamsB = PyList_New(n); //c++类型转python类型

		for (int i = 0; i < n; i++) {
			PyList_SetItem(pyParamsA, i, PyLong_FromLong(a[i]));
			PyList_SetItem(pyParamsB, i, PyLong_FromLong(b[i]));
		}

		long *result = new long(n);
		pArg = PyObject_CallFunction(pFunc, "OO", pyParamsA, pyParamsB); //调用函数
		for (int i = 0; i < n; i++) { // python类型转C++数组
			result[i] = PyLong_AsLong(PyList_GetItem(pArg, i));
			cout << result[i] << " ";
		}
		cout << endl;

		return result;
	}
}

点击运行,或者点击生成-》生成Dll1,
即可生成dll
在这里插入图片描述
红框是生成的dll所在路径。

错误1:无法打开文件“python310_d.lib”

需要安装PythonDebug版本
安装Python,如果已经安装Python,需要修改Python的安装设置,将Debug版本一起安装进来。
如果用anaconda安装的环境,需要重新下载python安装。
具体见https://www.jianshu.com/p/28291e95bed3和
https://blog.csdn.net/weixin_43788499/article/details/84933210

在这里插入图片描述
红框内要勾上。

警告:warning LNK4272: 库计算机类型“x86”与目标计算机类型“x64”冲突

使用的库是32位的而写的代码目标机器是64位的,所以报错产生冲突。
解决:下载使用32位的python
python官网:https://www.python.org/downloads/windows/
在这里插入图片描述

调用DLL

vs建立空项目:
在这里插入图片描述
在这里插入图片描述
在这个.cpp里写入

#include<iostream>
#include <Windows.h>
using namespace std;

int main()
{
	// 加载DLL文件
	HINSTANCE hDllInst;
	hDllInst = LoadLibrary(TEXT("DLL1.dll")); //调用DLL
	if (hDllInst) {
		typedef long* (*PLUSFUNC)(int* a, int* b, int n); //后边为参数,前面为返回值
		PLUSFUNC plus_str = (PLUSFUNC)GetProcAddress(hDllInst, "listAdd"); //GetProcAddress为获取该函数的地址
		int a[3] = { 1, 2, 3 }, b[3] = { 4, 5, 6 };
		long* result = plus_str(a, b, 3);
		cout << "调用完成" << endl;
	}
	else {
		cout << "DLL加载失败" << endl;
	}

	return 0;
}

配置一下项目属性,将之前生成的lib文件加入到链接器里面。
在这里插入图片描述
加入生成的lib的路径。

点击运行,输出

5 7 9
调用完成

错误1:已加载“C:\Windows\SysWOW64\ntdll.dll”。无法查找或打开 PDB 文件

解决:https://blog.csdn.net/u011251940/article/details/89521518
1、点 调试
2、然后 选项和设置
3、右边勾上 启用源服务器支持
4、左边点 符号
5、把微软符号服务器勾
6、确定保存。
再重新运行程序

在这里插入图片描述
在这里插入图片描述

错误2:找不到dll

要把dll文件放在debug文件夹里
在这里插入图片描述

错误2:找不到.py

把py文件放入
在这里插入图片描述

错误3:you should not try to import numpy from its source directory

我们进入python的路径里,
在这里插入图片描述
打开python.exe,输入import numpy 不报错,
打开python_d.exe,输入import numpy 报错。
说明,要尽可能让vs调用的是python.exe。
回到生成dll的步骤,在添加python依赖项:
在这里插入图片描述
一定要有python310.lib,如果只有python310.lib报错,
将python310_d.lib加入,但不要删除python310.lib。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1531209.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Visual Studio 2013 - 输出窗口一闪而过问题解决

Visual Studio 2013 - 输出窗口一闪而过问题解决 1. Visual Studio Console 一闪而过问题解决1.1. set Debug1.2. set Release References 1. Visual Studio Console 一闪而过问题解决 工程 -> 属性 -> 配置属性 -> 链接器 -> 系统 -> 子系统 -> 下拉框 -&g…

机器视觉系统选型-镜头参数

镜头参数&#xff1a; 光圈&#xff1a;光圈是一个用来控制镜头通光量的装置 &#xff0c;表示光圈大小我们是用光圈值&#xff08;F值&#xff09; &#xff0c;如F1.4&#xff0c;F2&#xff0c;F2.8 焦距&#xff08;Focus&#xff09;&#xff1a;透镜中心到其焦点的距离 景…

crossover虚拟机 crossover软件干嘛的 虚拟机软件的使用方法 mac虚拟机装windows

与传统的虚拟机软件&#xff08;如VMware、VirtualBox&#xff09;相比&#xff0c;CrossOver具有更高的运行效率和更好的用户体验。因为它并不创建一个完整的Windows虚拟机&#xff0c;而是仅模拟应用程序所需的运行环境。这使得CrossOver在启动和运行Windows应用程序时更加快…

平衡计分卡:企业/产品绩效管理的金钥匙

一、摘要 在企业管理领域&#xff0c;有一个广为流传的箴言&#xff1a;“衡量什么&#xff0c;得到什么。”这句话道出了衡量与结果之间的紧密关系。企业若想要取得理想的绩效&#xff0c;就必须建立科学、合理的衡量体系。而平衡计分卡&#xff0c;正是这样一套能够全面、系…

#Ubuntu(修改root信息)

&#xff08;一&#xff09;发行版&#xff1a;Ubuntu16.04.7 &#xff08;二&#xff09;记录&#xff1a; &#xff08;1&#xff09;命令行终端&#xff1a; a.右键&#xff0c;open terminal b.快捷键 ctrlaltt &#xff08;2&#xff09;进行root修改 sudo passwd &a…

【09】进阶JavaScript事件循环Promise

一、事件循环 浏览器的进程模型 何为进程? 程序运行需要有它自己专属的内存空间,可以把这块内存空间简单的理解为进程 每个应用至少有一个进程,进程之间相互独立,即使要通信,也需要双方同意。 何为线程? 有了进程后,就可以运行程序的代码了。 运行代码的「人」称之…

【web世界探险家】HTML5 探索与实践

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &…

【MySQL | 第五篇】MySQL事务总结

文章目录 5.MySQL事务5.1什么是事务&#xff1f;5.2什么是数据库事务&#xff1f;5.3数据库事务四大特性5.4并发事务带来的问题及解决方案&#xff1f;5.4.1脏读/不可重复读/幻读5.4.2不可重复读和幻读有什么区别&#xff1f;5.4.3解决并发事务带来的问题&#xff08;1&#xf…

windows服务器iis更换彻底删除 原443 ssl证书以及一个服务器运行多个独立域名网站并绑定多个证书的方法

服务器上的433 ssl证书,可以让网站以https加密方式访问,但是这个证书会占用443端口,iis7版本,只能安装一个443证书,所以.原来的过期了.需要删除.删除方式,不是进运行 winr的mmc 而是进iis的默认的总的主页面板(不是点击具体的网站或者程序池),点击服务器证书.进去才能删除.否则…

5G网络架构及技术(一):入门级介绍

参考资料&#xff1a; [1] 5G网络架构&#xff0c;March 15, 2020 / By Adnan Ghayas [2] 5G应用场景&#xff0c;June 2, 2021 / By Adnan Ghayas [3] 独立和非独立5G网络&#xff0c;September 19, 2020 / By Adnan Ghayas 5G网络架构&#xff08;一&#xff09;&#xff1a;…

人类与AI:谁做出最好的决定?

此为看完视频Humans vs. AI: who makes the best decisions?后的笔记。 对于不同的任务&#xff0c;AI和人类各有擅长。 在本视频中&#xff0c;作者具化到了一个欺诈检测系统。欺诈检测系统会生成潜在欺诈交易的警报&#xff0c;金融分析师会审查每个警报。但每天都会生成数…

Javascript的Execution Context

概要 本文主要通过一个实例&#xff0c;来理解什么是Javascript中的Execution Context&#xff0c;以及在JavaScript执行过程中&#xff0c;Execution Context是如何工作的。 基本概念 事实上&#xff0c;我们可以理解为JavaScript代码在一个盒子中执行&#xff0c;而这个盒…

IDC:2027年中国网络安全市场规模将超200亿美元

IDC于近日发布了2024年V1版IDC《全球网络安全支出指南》(IDC Worldwide Security Spending Guide)。IDC数据显示&#xff0c;2022年全球网络安全IT总投资规模为1890.1亿美元&#xff0c;并有望在2027年增至3288.8亿美元&#xff0c;五年复合增长率&#xff08;CAGR&#xff09;…

阅读笔记(CVPR2020)Warping Residual Based Image Stitching for Large Parallax

基于变形残差的大视差图像拼接 K. -Y. Lee and J. -Y. Sim, "Warping Residual Based Image Stitching for Large Parallax," 2020 IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR), Seattle, WA, USA, 2020, pp. 8195-8203, doi: 10.1109/…

重学SpringBoot3-函数式Web

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-函数式Web 函数式Web编程简介RouterFunctionRequestPredicateServerRequestServerResponse 好处示例结论 随着响应式编程范式的兴起和 Java 函数式编程能…

回来了,你瞧不上的中文编程

谈及中文编程&#xff0c;我们无法绕过一个开创性的里程碑——“易语言”。这款编程语言以“易”为核心理念&#xff0c;独树一帜地采用全中文支持&#xff0c;不仅显著降低了编程的门槛&#xff0c;更承载了无数人的“民族语言编程梦想”。 回溯到21世纪初的2000年9月&#xf…

详细分析Js中的Promise.all基本知识(附Demo)

目录 1. 基本知识2. Demo3. 实战 1. 基本知识 Promise.all 是 JavaScript 中的一个方法&#xff0c;它接受一个由 Promise 对象组成的数组作为参数&#xff0c;并在所有 Promise 对象都变为 resolved&#xff08;已完成&#xff09;状态时才返回一个新的 Promise 对象&#xf…

扫码收集用户数据怎么做?创建问卷表单二维码的方法

现在通过扫描二维码的方式来收集用户数据&#xff0c;比如制作问卷、签到表、信息登记等类型都可以通过生成表单二维码的形式来做数据采集。现在大部分都习惯通过二维码来获取内容&#xff0c;所以扫码填表的方式更符合现在人的生活习惯&#xff0c;有利于快速收集用户数据&…

51单片机-蜂鸣器

1.蜂鸣器的介绍 无源蜂鸣器不能一直通电&#xff0c;无源蜂鸣器内部的线圈较小&#xff0c;易烧坏 蜂鸣器的驱动 达林顿晶体管&#xff08;npn型&#xff09; 应用&#xff1a; 按下独立按键同时蜂鸣器响起提示音&#xff0c;数码管显示对应的独立按键键码 #include <REG…

【进阶五】Python实现SDVRP(需求拆分)常见求解算法——差分进化算法(DE)

基于python语言&#xff0c;采用经典差分进化算法&#xff08;DE&#xff09;对 需求拆分车辆路径规划问题&#xff08;SDVRP&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整3. 求解结果4. 代码片段参考 往期优质资源 经过一年多的创作&#xff0c;目前已经成…