Boost之Python

Boost.Python 是一个用于实现 C++ 和 Python 之间互操作性的库,它的主要功能包括:

  • 转换接口:允许开发者将 C++ 函数和类转换为 Python 可调用的形式,这样在 Python 中就可以直接使用这些 C++ 代码。
  • 简化过程:在很多情况下,开发者不需要对原始的 C++ 代码进行任何修改。Boost.Python 会对 C++ 类进行封装,使其编译后符合 Python 的语言规范,从而简化了集成过程。
  • 导出对象和方法:可以将 C++ 的函数和对象导出,使得 Python 能够方便地调用这些对象和方法,这是实现 C++ 和 Python 混合编程的关键功能。
  • 基本类型导出:提供了一系列的格式和关键字来导出基本类型,例如使用 boost::python::def() 来定义一个可以被 Python 调用的 C++ 函数。
  • 模块定义:通过 BOOST_PYTHON_MODULE 宏,可以定义一个可以被 Python 导入的模块,这样可以组织和管理 C++ 提供的接口。

C++编写Python扩展模块:

       可以向python暴露C++类中的成员函数和成员数据,直接供python使用

#include <boost/python.hpp>
using namespace boost::python;
#include <iostream>
using namespace std;

struct World
{
    World(){
        cout << "World()" << endl;
    }
    World(const string& str){
        msg = str;
        cout << "World(const string& str)" << endl;
    }
    World(double,double){
        cout << "World(double,double)" << endl;
    }
    void set(std::string msg) { this->msg = msg; }
    double getMyData(){return data2;}
    void setMyData(double d){data2 = d;}
    
    std::string greet() { return msg; }
    std::string msg;
    string name="World AAAAA";
    double data;
    double data2;


};

BOOST_PYTHON_MODULE(hello)
{
    class_<World>("World", init<string>())           //定义python类的构造函数
        .def(init<double,double>())                  //另一个构造函数
        .def("greet", &World::greet)                 //暴露普通函数
        .def("set", &World::set)
        .def_readonly("myName", &World::name)        //暴露成员数据(只读)
        .def_readwrite("myData", &World::data)       //暴露成员数据 (读写)
        .add_property("myData2", &World::getMyData, &World::setMyData) //暴露属性(属性名和C++成员名可以不同)
    ;
}

vcpkg+cmake编译代码,生成动态库(linux环境):

project(hello)

add_library(${PROJECT_NAME} SHARED 2.cc)

#不要动态库前缀,生成的动态库名为:hello.so
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
find_package(Boost REQUIRED python311)
find_package(Python3 COMPONENTS Development REQUIRED)
#正常来说应该是Boost::python,但是我的电脑上必须是Boost::python311, 可能是vcpkg的boost上的bug
target_link_libraries(${PROJECT_NAME} PRIVATE Boost::python311 Python3::Python)

python代码中使用生成的动态库:

Boost::Python 不仅能够将 C++ 代码暴露给 Python,还支持在 C++ 中直接调用 Python 脚本。以下是一些关于如何在 C++ 中使用 Boost::Python 来调用 Python 脚本的功能介绍:

  • 调用Python函数:可以在C++中直接调用Python脚本中定义的函数。这通常涉及到使用boost::python::import()来导入Python模块,然后通过boost::python::object来调用模块中的函数。
  • 执行Python脚本:可以执行Python脚本文件中的代码。这通常需要确保Python脚本文件位于程序的工作目录下,然后在C++代码中指定要执行的Python脚本路径。
  • 数据交互:在C++和Python之间传递数据,例如,可以从C++传递参数给Python函数,或者从Python函数返回值给C++程序。
  • 类型转换:自动处理C++和Python之间的数据类型转换,使得两种语言间的数据可以安全、正确地传递。

需要注意的是,尽管 Boost::Python 提供了许多便利的功能,但它的实现依赖于 Python/C API,因此在使用时要结合 Python/C API 的相关知识。此外,Boost::Python 的某些功能可能还不完善,需要开发者对 Python/C API 有一定的了解,以便在遇到问题时能够进行调试和解决。

C++中调用Python脚本:

#include <boost/python.hpp> // Boost.Python
#include <iostream>
#include <string>
using namespace std;
using namespace boost::python;

int main(int argc, char* argv[])
{
    Py_Initialize(); // 初始化 Python 解释器
 
    try
    {
        object main_module = import("__main__");
        object main_namespace = main_module.attr("__dict__");
        exec("import sys", main_namespace);
        exec("sys.path.append('')", main_namespace); // 将当前目录添加到Python模块搜索路径

        object m = import("MyTest");
        object getPidName = m.attr("GetPidName");
        object getPids = m.attr("GetPidList");
        list lstPid = extract<list>(getPids());

        for(int i = 0; i < len(lstPid); i++){
            int id = extract<int>(lstPid[i]);
            object name = getPidName(id);
            str sName = extract<str>(name);
            string strName = extract<string>(name);
            cout << strName << endl;
        }
    }
    catch (const error_already_set&)
    {
        PyErr_Print();
        return -1;
    }
 
    Py_Finalize(); // 终止 Python 解释器
 
    return 0;
}

MyTest.py

#!/usr/bin/python3.11
#encoding=utf-8

import psutil

def GetPidName(pid):
    return psutil.Process(pid).name()

def GetPidList():
    return psutil.pids()

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值