前言
python有很多很好用的库,可以很快构建好一个demo,但是当我们需要封装gui的时候,使用python会非常难受,构建的exe文件可能非常大,比如我想实现一个yolov8的屏幕实时检测,会构建达到2.7g。这对于开发会非常难受,于是我们可以采取利用python写必要的功能,再用C++来调用,达到减小构建exe文件的工程量。
1.编写 Python 文件 my_module.py
:
# my_module.py
def add_numbers(a, b):
return a + b
- 安装Cython:
pip install cython
- 创建一个
.pyx
文件,比如my_module.pyx
,其中包含你想要封装的Python代码。 - 创建一个
setup.py
文件,用于构建DLL文件:
2.创建Cython包装器(my_module.pyx
):
# my_module.pyx
def add_numbers(a, b):
return a + b
# setup.py
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules=cythonize("my_module.pyx"),
)
创建my_module.pyx和setup.py文件,其中my_module是模块名字,可任意修改。
3.构建动态库(dll)文件:
pip install cython
python setup.py build_ext --inplace
构建成功后,文件在当前文件夹的build文件夹内。
4.创建C++调用DLL的代码(main.cpp
):
// C++ 代码
#include <iostream>
#include <Python.h>
int main() {
Py_Initialize();
// 导入 Python 模块
PyObject* pModule = PyImport_ImportModule("example");
if (pModule != NULL) {
// 获取 Python 函数
PyObject* pFunction = PyObject_GetAttrString(pModule, "my_function");
if (pFunction != NULL && PyCallable_Check(pFunction)) {
// 调用 Python 函数
PyObject_CallObject(pFunction, NULL);
// 不需要处理返回值,因为 Python 函数没有返回值
Py_DECREF(pFunction);
} else {
PyErr_Print();
}
Py_DECREF(pModule);
} else {
PyErr_Print();
}
Py_Finalize();
return 0;
}
这个C++代码加载my_module.pyd
并调用其中的add_numbers
函数。
如果运行不成功,请看后文注意
5.编译和运行:
使用你的C++编译器(如g++, Visual C++等)编译main.cpp
,确保链接到my_module.pyd
。然后运行生成的可执行文件,你应该能够看到输出结果。
注意!!
1.如果出现未找到Python.h问题时,需要在环境中引用当前系统的python环境,例如我使用conda的虚拟环境则为D:\anaconda3\envs\y8\include;还需引用库文件,路径为D:\anaconda3\envs\y8\libs;再添加依赖项python312.lib