1、前言
算法开发时,有些部署流程比较繁琐。且坑比较多。以下写一个小的demo。将python程序打包成so库。并用c++调用。我这里时基于vscode开发的。
2、python demo
2.1 依赖安装
pip install cython -i https://pypi.tuna.tsinghua.edu.cn/simple
这条命令中的-i
选项用于指定pip使用的镜像源,https://pypi.tuna.tsinghua.edu.cn/simple
是清华大学的PyPI镜像源地址,它可以提供更快的下载速度,特别是在国内网络环境下。
永久配置清华源的方法如下:
1)如果你希望每次使用pip时都默认使用清华源,可以通过修改pip的配置文件来实现。在Windows上,找到或创建pip.ini
文件(通常位于C:\Users\<YourUsername>\pip\pip.ini
),并添加以下内容:
[global]
index-url=https://pypi.tuna.tsinghua.edu.cn/simple
2)在macOS和Linux上,找到或创建pip.conf
文件(通常位于\~/.pip/pip.conf
),并添加相同的内容。
配置完成后,你就可以像平常一样使用pip安装Python包了,pip会自动从清华源下载包。但请记住,你实际上安装的是Python的包或库,而不是cpython
本身。cpython
是Python的底层实现,它随着Python的安装程序一起被安装在你的系统上。
如果你想要安装特定版本的Python,你需要从Python的官方网站下载相应版本的安装包进行安装,而不是通过pip命令。在安装过程中,你可以选择是否将Python添加到系统的PATH环境变量中,以便在命令行中方便地运行Python。
2.2 程序demo
1、首先编写需要执行的程序。
# hello.pyx
def hello():
return "Hello from Python!"
将后者替换为.pyx
2、编译
接下来,编写一个setup.py
脚本来编译Python代码为动态库。确保你已经安装了Cython(可以通过pip install cython
来安装)。
# setup.py
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("hello.pyx"),
)
执行bash脚本进行编译
python setup.py build_ext --inplace
执行后,会在当前目录下生成动态库。
3、c++程序调用
#include <Python.h>
int main(int argc, char *argv[]) {
// 初始化Python解释器
Py_Initialize();
// 添加当前路径到python路径(非常重要,不然会找不到这个so模块)
PyRun_SimpleString("import sys\nsys.path.append('.'))
// 加载Cython编译的.so模块
PyObject* pName = PyUnicode_DecodeFSDefault("hello"); // your_cython_module
PyObject* pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != nullptr) {
// 获取模块中的函数
PyObject* pFunc = PyObject_GetAttrString(pModule, "hello"); // your_cython_function
// 检查函数是否可调用
if (pFunc && PyCallable_Check(pFunc)) {
// 准备函数参数(这里假设函数不接受参数)
PyObject* pArgs = PyTuple_Pack(0);
// 调用函数
PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
// 处理返回值(这里只是简单地打印出来)
if (pValue != nullptr) {
printf("Result of call: %s\n", PyUnicode_AsUTF8(pValue));
Py_DECREF(pValue);
} else {
PyErr_Print();
fprintf(stderr, "Function call failed\n");
}
Py_DECREF(pFunc);
} else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function 'your_cython_function'\n");
}
Py_DECREF(pModule);
} else {
PyErr_Print();
fprintf(stderr, "Failed to load 'your_cython_module'\n");
}
// 终止Python解释器
Py_Finalize();
return 0;
}
4、编译执行
要编译并执行一个包含Python C API调用的C++程序,你需要确保你的系统上安装了Python开发包(通常包括Python头文件和库)。编译过程通常分为两个步骤:首先是编译C++代码,然后是链接生成可执行文件。
下面是一个简化的编译和执行过程的示例,基于上面的代码片段。请注意,这个例子假设你使用的是g++编译器,并且Python的安装路径是标准的(/usr/include/pythonX.Y和/usr/lib/pythonX.Y,其中X.Y是Python的版本号)。如果你的Python安装在不同的位置,你可能需要调整编译器的包含目录和链接目录。
首先,确保你的C++代码保存为一个文件,比如main.cpp
。
然后,在终端中执行以下命令来编译代码:
g++ -o my_program main.cpp -I/usr/include/python3.X -lpython3.X
在这里,my_program
是你想要生成的可执行文件的名称,main.cpp
是你的C++源文件名,-I/usr/include/python3.X
指定了Python头文件的搜索路径(替换X为你的Python次版本号,比如8对于Python 3.8),-lpython3.X
指定了要链接的Python库(同样替换X为版本号)。
编译成功后,你可以通过以下命令来运行生成的可执行文件:
./my_program