C++调用python代码

本文介绍如何在C++环境中调用Python的SVM模型,包括环境配置、数据类型转换等关键技术点,并提供了一个简单的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【需求】:使用c++调用python中sklearn包的SVM,训练+识别。
【需要解决的问题】:相关的环境配置,c++与python数据类型的互转,不安装python的环境下运行。

【测试用的python包】:python2.7.14-32位
【测试用的vs工程】:debug 32位

【步骤】:(具体的示例,在这里
1. 先配置VS的项目属性,一个是包含目录,一个是库目录。
包含目录添加python根目录下的include文件夹;库目录添加python根目录下的Lib文件夹。
lib文件夹里放【python27.lib文件】和【python27_d.lib文件】,我现在debug32位下用的就是【python27_d.lib文件】。

2. 把【python27.dll文件】和C++要调用的【.py文件】都放到工程下debug文件夹下,也就是跟【.exe文件】相同目录下。
当前还有python环境时,【python27.dll文件】在你安装python后的C盘windows\SysWOW64文件夹下。

3. 在vs环境下调试时,需要将Python27文件夹放到调用python代码的【.cpp文件】同目录中;在软件发布后运行时,Python27文件夹放到【.exe文件】相同目录下。

4. C++的代码中添加Python.h头文件。

【使用的几个API函数】:
1. Py_SetPythonHome( "路径")
    设置运行py文件时,搜索依赖文件的路径。
2. Py_Initialize( )和Py_Finalize( )
    成对儿出现,用在调用python的头尾。
3. PyImport_ImportModule("py的文件名")
    纯文件名,不包含".py"这几个字符,返回一个PyObject类型的指针,例如拿PyObject* pModule接收返回值。
4. PyObject_GetAttrString(pModule, "wcyaaa")
    拿到python中函数的索引,上面的pModule放到第一个参数,表示从这个py文件里取数据;后面第二个参数是要调用的python函数的函数名。
    返回一个PyObject类型的指针,例如拿PyObject* pFunc接收返回值。
5. PyEval_CallObject(pFunc, NULL)

    调用pFunc对应的那个python中的函数,上面的pFunc放到第一个参数,表示调用这个函数;后面第二个参数是要传入python函数的参数。这里调用的是无参的函数,就填NULL。
    返回的内容为python函数的返回值,类型仍是PyObject*。
6. PyTuple_New(参数个数)
    如果需要传参数到python函数中,那这里就将“传参个数”设置成对应的数量。传元组就类似C++中的const,不能改。
    返回值同样是PyObject类型的指针,例如拿PyObject *pArgs接收返回值。

7. PyTuple_SetItem(pArgs, 0, variable)
    第一个参数就是负责传递参数的管道,也就是那个元组;第二个参数是这个元组中的第几个元素;第三个参数是要放入元组对应位置的数据(这个需要是 PyObject * )。
    调用函数传参时,就这么写:PyEval_CallObject(pFunc, pArgs)
8. Py_BuildValue("i",variable)
    将C++的数据结构转成python的数据结构。第一个参数是格式设定,第二个参数是待转换的C++变量。
9. PyArg_Parse(pVal, "i", &result)
    将python的数据结构转换成C++的数据结构。第一个参数是接收的python函数的返回值;第二个参数是参数设定;第三个参数是用来接收转换后C++类型的数据。

【不安装python环境运行】:
在运行python程序之前,也就是Py_Initialize( )之前调用一下Py_SetPythonHome( "路径"),把搜索依赖文件的路径设置成Python27文件夹的路径,就ok了。

示例代码里面有很多不足:
比如构造二维嵌套的list时,直接粗暴的13个值塞进去了,其实可以分层来造;

包含的Python27文件夹中文件比较多,回头再精简一下。可根据下面几个博客来尝试提取。
嵌入python的c++程序发布(二)最小化抽取需要的模块 - 优快云博客
C中嵌入Python解释器 - 优快云博客
VS2010 c++内嵌python环境以及生成发布安装包 - 优快云博客
嵌入python的c++程序发布(一)最简单的方法 - 优快云博客

### 如何从C++调用Python代码 为了实现从C++环境中执行Python代码的功能,可以采用多种方法和技术栈。其中一种常见的方式是通过Boost.Python库来完成这一目标;另一种方式则是利用SIP工具。 当使用Boost.Python时,开发者可以在C++项目里嵌入Python解释器并交互式地运行Python脚本或模块[^3]。下面展示了一个简单的例子说明怎样创建一个能够调用Python函数的C++应用程序: #### 使用Boost.Python调用Python代码 首先,在C++端初始化Python环境,并导入所需的Python模块: ```cpp #include <boost/python.hpp> namespace py = boost::python; int main(){ Py_Initialize(); // 初始化Python解释器 try { py::object main_module = py::import("__main__"); py::object global_namespace = main_module.attr("__dict__"); // 导入Python文件作为模块 py::object my_script = py::exec_file("example.py", global_namespace); // 调用Python中的函数 py::object result = py::eval("my_function()", global_namespace); std::cout << "Result from Python function: "; std::cout << py::extract<int>(result) << std::endl; } catch(const py::error_already_set&) { PyErr_Print(); } Py_Finalize(); // 关闭Python解释器 } ``` 对于上述代码片段而言,`example.py`应该预先存在并且包含名为`my_function()`的方法定义。此方法接受参数并通过返回整数值响应给C++程序。 另外,如果倾向于更轻量级的选择,则可以选择SIP工具来进行类似的跨语言编程操作[^1]。然而需要注意的是,虽然SIP支持Python缓冲区接口使得某些类型的转换变得容易处理[^2],但在实际应用过程中可能仍需额外配置才能顺利工作。 最后值得注意的一点是在设计此类混合型解决方案时要特别关注内存管理和线程安全等问题,因为不同语言之间的边界往往隐藏着潜在的风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值