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

最近需要将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。

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyInstaller并不支持直接将Python代码打包dll文件,因为Python代码需要被解释器解释才能运行,而dll文件是编译后的二进制文件,无法被解释器解释。 不过,可以使用Cython将Python代码编译C代码,然后再将其编译dll文件。Cython是一个能够将Python代码转换为C代码的工具,可以将Python代码中的部分代码编译C代码,从而提高程序的性能。 以下是使用Cython将Python代码打包dll文件的大致步骤: 1. 安装Cython。可以使用以下命令安装Cython: ``` pip install Cython ``` 2. 将Python代码转换为C代码。使用Cython将Python代码转换为C代码。例如,如果要将名为`my_module.py`的Python模块转换C代码,可以使用以下命令: ``` cython my_module.py ``` 这将生一个名为`my_module.c`的C代码文件。 3. 编译C代码为dll文件。使用C编译器将C代码编译为dll文件。例如,在Windows平台上,可以使用以下命令: ``` cl /LD /I "C:\Python\include" my_module.c /link /LIBPATH:"C:\Python\libs" /OUT:my_module.dll ``` 这将编译`my_module.c`为名为`my_module.dll`的dll文件。需要将`/I`和`/LIBPATH`参数替换为你的Python安装路径和libs路径。 需要注意的是,使用Cython将Python代码转换为C代码时,需要将原有的Python代码中的一部分代码进行修改,以便能够编译C代码。同时,编译dll文件时也需要根据操作系统和Python版本进行相应的调整。 希望以上步骤可以帮助你使用Cython将Python代码打包dll文件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值