Visual studio 2022 编译 python c c 扩展 - housekeeper-software/tech GitHub Wiki
当一个任务用python实现效率太低的时候,可以考虑用C++实现。numpy,pytorch,tensorflow底层都是c++编写的,然后用python进行高层接口封装
安装Python,注意,不要安装比较新的版本,尤其是最新版,因为优化了GIL,导致vs不能调试。所以,我们安装3.9版本。
在安装时,记得选择 Debug 符号,这样才可以编译Debug版本,进而可以调试c/c++扩展。
安装 Visual studio Community 2022,记得安装:
C/C++
Python 开发,需勾选 Python 本机开发工具
1.新建一个工程目录
2.通过 Python应用程序模板新建一个Python工程
3.在此解决方案中添加一个c++空项目。
假设工程名字为 testc
1.在解决方案中右键点击C++工程->属性
2.选择x64(if x64 platform):
(1)配置属性->常规->目标文件名
如果想要把testc作为私有模块,那么这里写入 _$(ProjectName)_d,前面的下划线表示私有模块,
如果不是私有的模块,则不需要前面的下划线,后面的_d表示Debug,如果是Release则不需要_d
(2) 目标类型: 动态库(.dll)
(3) 配置属性->高级->目标文件扩展名: .pyd,这是Windows下的c++扩展,Linux下的就是so即可。pyd就是dll。
(4) 配置属性->C/C++->附加包含目录,设置为Python安装目录的include,比如: D:\Users\zxm\Python\Python39\include
(5) 配置属性->连接器->附加库目录,设置为Python安装目录的libs目录,比如: D:\Users\zxm\Python\Python39\libs
(6) 配置属性->连接器->输入->附加依赖项,这个不用设置,vs自动根据情况添加python.lib之类的
1.在解决方案中右键点击 python工程->属性
2.在[调试]中"启用本机代码调试",同时,在解释器参数中输入 -i ,表示进入python交互控制台
3.在解决方案中,为python工程添加引用,指向刚才的C++工程。编译c++的时候,最后的输出被指向到python工程的输出目录,比如 x64/Debug,同时
vs会自动将x64/Debug添加到os.path中,这样python就可以找到这个扩展
写代码:
#include <Python.h>
...
static PyMethodDef testc_functions[] = {
{"CreateIoCompletionPort", completion_CreateIoCompletionPort,
METH_VARARGS, CreateIoCompletionPort_doc},
{"GetQueuedCompletionStatus", completion_GetQueuedCompletionStatus,
METH_VARARGS, GetQueuedCompletionStatus_doc},
{"PostQueuedCompletionStatus", completion_PostQueuedCompletionStatus,
METH_VARARGS, PostQueuedCompletionStatus_doc},
{NULL}
};
static struct PyModuleDef testc_module = {
PyModuleDef_HEAD_INIT,
"_testc",
NULL,
-1,
testc_functions,
NULL,
NULL,
NULL,
NULL
};
PyMODINIT_FUNC
PyInit__testc(void) {
return PyModule_Create(&testc_module);
}
这里需要注意,PyInit__testc中有两个下划线,它的规则是 PyInit_模块名,因为我们这里假设是私有模块,本身前面有个下划线,
所以这里有两个,如果不是私有包,那只有一个。
###,在调用WinAPI的前面添加:
Py_BEGIN_ALLOW_THREADS;
ret = GetQueuedCompletionStatus(CompletionPort, &NumberOfBytes,
&CompletionKey, &Overlapped, Milliseconds);
Py_END_ALLOW_THREADS;
意思是:在调用Windows Native API之前释放GIL锁,交出控制权,之后再申请控制权
在解决方案中点击c++工程进行编译,此刻我们编译出Debug版本。它输出到python工程的x64/Debug目录,包含4个文件,其中:
_testc_d.pyd就是c++扩展模块
# 编写python工程
import _testc ...
# 混合调试python和C++工程
在c++工程代码中需要调试的位置打断点,将python设置为启动项目,其中入口文件设置为启动文件 在python代码中打断点,按下F5进入调试
# 安装
写 setup.py,包含自动编译和安装,最后生成whl包