IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 使用vscode+msvc为python编写c/c++扩展 -> 正文阅读

[C++知识库]使用vscode+msvc为python编写c/c++扩展

使用vscode+msvc为python编写c/c++扩展

博主近期因为项目中暴露的性能问题😥,需要为python编写一个c++的扩展,以达到提高运行效率的目的,故借此机会了解了利用python自带的C类库来编写C/C++扩展的具体实现方法,在此记录一下。

这里使用的python版本为3.10.2, 使用的是vs build tool 2022提供的msvc进行编写

一、配置vscode+msvc环境

本文使用的vscode和vs build tool 2022来实现环境的搭建,这里默认已经安装好了mscv以及vscode的c++相关插件。

首先新建一个文件夹,作为工作空间,并在其中新建一个source文件夹用于存放源代码,一个build文件夹用来存储编译之后的结果。
工作空间

打开开始菜单,找到vs2022的文件夹,并选择对应版本的控制台打开。(选择X86还是X64版本的控制台取决于python的版本,这里务必保持和python一致。博主使用的是x64版本的python,故打开对应的x64版本控制台)在打开控制台之后,将路径切换到刚刚创建好的工作空间目录下,输入"code ."打开vscode。
vs控制台
在source文件夹下新建一个main.cpp文件,并写入一个简单的hello world程序,用于之后的测试
main.cpp
点击F5运行代码,会看到vscode出现弹窗。我们使用的是msvc,因此应该选择C++(windows)
编译器选择
之后的一个弹窗选择cl.exe
编译器选择
可以看到运行的结果,说明我们msvc配置成功了👍
运行结果

由于本文涉及的内容并没有调试的过程,因此此处不再演示如何进行debug,若读者有这方面的需求,可以参考vscode官网的c++文档,里面有更为详细的过程👆

二、编写c++部分代码

此时可以看的工作空间的目录下,vscode自动生成了一个task.json配置文件(如下图所示)
task.json
其中args数组中是cl的配置项,目前是最基础的配置,如果需要编写python的扩展,那么还需要对其进行调整,这里我直接展示调整之后的task.json文件
task.json
这里介绍一下对应的修改项以及其意义

  • /LD:编译动态链接库
  • /Fe:编译链接之后的生成的文件名,其后面跟随编译所需要的源文件,vscode的默认配置只能编译一个文件,这里将其调整为可以编译多个文件,并修改了生成路径。
  • /I:添加头文件依赖。我们需要借助python提供的python.h在进行编写扩展,所以这里需要把这个头文件所在的路径告知给cl(图中的为博主的路径,在使用时只需要替换为自己python头文件所在路径即可,下面的库文件路径同理)
  • /link:链接器选项, 这个选项之后的配置都是针对link.exe的配置
  • /MACHINE :将目标文件的类型调整为x64(x86同理,但一定保证和python的类型一样)
  • /LIBPATH: python库文件所在的地址

将参数调整好之后,便可以开始进行编码了。这里附上python官方提供的原版教程以供参考。本文用一个简单的案例来演示,先上代码。

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

int Add(int x, int y){
    return x + y;
}

void Print(char* str){
    std::cout<<str<<std::endl;
}

static PyObject* py_add(PyObject* self, PyObject* args){
    int x, y;
    if(!PyArg_ParseTuple(args, "ii", &x, &y))
        return NULL;
    return Py_BuildValue("i", Add(x, y));
}

static PyObject* py_print(PyObject* self, PyObject* args){
    char* str;
    if(!PyArg_ParseTuple(args, "s", &str))
        return NULL;
    Print(str);
    Py_INCREF(Py_None);
    return Py_None;
}

static PyMethodDef pymethods[] = {
    {"my_add", py_add, METH_VARARGS, "加法"},
    {"my_print", py_print, METH_VARARGS, "打印"},
    {NULL, NULL, 0, NULL}
};

static PyModuleDef mymodule = {
    PyModuleDef_HEAD_INIT,
    "mymodule",
    NULL,
    -1,
    pymethods
};

extern "C"
PyMODINIT_FUNC
PyInit_mymodule(void){
    return PyModule_Create(&mymodule);
}

先简单写两个函数,一个实现加法,一个实现打印。为了让python可以识别,需要对它们使用Python.h提供的PyObject来封装。

每个返回PyObject的函数都有两个固定参数,self和args。函数中的PyArg_ParseTuple用来将python形式的参数映射为C类型的数据。函数的返回值可以使用Py_BuildValue进行封装,以转换成python可以识别的类型。这里需要注意的是,如果函数没有任何需要返回的值,那么需要让函数返回None,具体方式见py_print()函数。

在函数封装完毕后,将方法打包进PyMethodDef结构体中,这个结构体数组中每一项的四个值分别对应:

  • python调用的接口名称
  • 封装好的函数的函数名
  • METH_VARARGS(参数对应模式,另外还有关键字对应方式,详情请查看python官网文档)
  • 注释

将全部函数打包好之后,便可以开始打包模型了,也就是代码中的PyModuleDef,这里比较重要的是第二个值,这个值是模块的名称。

最后编写PyInit函数用来生成之前打包好的模组,此处的格式较为固定,需要注意的是PyInit_name()中,name是打包模组的名称,python在第一次执行我们打包的模块时会调用这个函数。在编写好全部代码后,使用快捷键"shift+ctrl+B"编译代码。

上述代码中有一点会出现问题,及python.h可能不能被识别到,此时需要添加c/c++语言配置文件,并将python.h所在的路径添加到其中的includePath中

三、Python调用动态链接库

在编译链接之后,build文件夹下应该会有若干文件生成,如下图

生成结果

其中dll动态链接库就是打包好的C++扩展,不过python不能直接识别dll文件,需要先将其重命名为.pyd格式,再使用import进行引入。
下面调用模型的接口进行测试

import mymodule as md

md.my_print("hello world")
print(md.my_add(1, 1))

可以得到输出的结果,说明打包成功😊
结果

本文为本人的学习笔记,如有问题欢迎指出和讨论@茱莉亚之歌

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:14:26  更:2022-03-12 17:17:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:05:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码