你将学到什么

  • 在Python中调用C++代码时的传参问题

基础类型

Python的字符串是常量,所以C++函数参数中的std::string &必须为const

修改源文件(main.cpp)

#include <iostream>
#include <boost/python.hpp>
#include "boost_wrapper.h" using namespace boost::python;
using namespace boost::python::detail; int main()
{
Py_Initialize();
if (!Py_IsInitialized())
{
std::cout << "Initialize failed" << std::endl;
return -1;
} try
{
object sys_module = import("sys");
str module_directory(".");
sys_module.attr("path").attr("insert")(1, module_directory);
object module = import("zoo");
module.attr("show")();
}
catch (const error_already_set&)
{
PyErr_Print();
}
Py_Finalize();
return 0;
}

Python脚本如下(build/zoo.py)

import boost

def show():
boost.add(2, 4)
boost.xstr("fwd") if __name__ == '__main__':
pass

导出头文件如下(include/boost_wrapper.h)

#pragma once

#include <string>

void add(int x, int y);
void xstr(std::string const &x);

导出实现如下(src/boost_wrapper.cpp)

#include <iostream>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include "boost_wrapper.h" using namespace boost::python;
using namespace boost::python::detail; void add(int x, int y)
{
std::cout << "add: " << x + y << std::endl;
} void xstr(std::string const &x)
{
std::cout << "string: " << x << std::endl;
} BOOST_PYTHON_MODULE_INIT(boost)
{
def("add", add);
def("xstr", xstr);
}

标准库

修改源文件(main.cpp)

#include <iostream>
#include <boost/python.hpp>
#include "boost_wrapper.h" using namespace boost::python;
using namespace boost::python::detail; int main()
{
Py_Initialize();
if (!Py_IsInitialized())
{
std::cout << "Initialize failed" << std::endl;
return -1;
} try
{
object sys_module = import("sys");
str module_directory(".");
sys_module.attr("path").attr("insert")(1, module_directory);
object module = import("zoo");
module.attr("show")();
}
catch (const error_already_set&)
{
PyErr_Print();
}
Py_Finalize();
return 0;
}

方式一

这种方式主要使用vector_indexing_suite定义一个新的Vector类型XVec

Python脚本如下(build/zoo.py)

import boost

def show():
l = boost.XVec()
l.append(2)
l.append(3)
l.append(4)
boost.show_list(l)
for i in l:
print(i) if __name__ == '__main__':
pass

导出头文件如下(include/boost_wrapper.h)

#pragma once

#include <vector>

void show_list(std::vector<int> &v);

导出实现如下(src/boost_wrapper.cpp)

#include <iostream>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include "boost_wrapper.h" using namespace boost::python;
using namespace boost::python::detail; void show_list(std::vector<int> &v)
{
for (auto item : v)
{
std::cout << item << " ";
}
std::cout << std::endl;
v.push_back(7);
} BOOST_PYTHON_MODULE_INIT(boost)
{
class_<std::vector<int> >("XVec").def(vector_indexing_suite<std::vector<int> >());
def("show_list", show_list);
}

方式二

这种方式主要是通过boost :: python :: converter :: registry :: push_back函数来注册自定义转换函数,主要实现两个函数convertible(用于检测Python侧传入的对象是否符合转换条件,比如是不是迭代器、里面的元素类型是不是对的等,这边只是简单实现下)和construct(提取Python侧传入的对象元素,然后构造C++侧的对象,这边也只是简单实现了下),高级实现方式可以参考cctbx_projectscitbx/array_family/boost_python/regress_test_ext.cppscitbx/boost_python/container_conversions.h文件,不过参数必须是右值(注意函数参数的const修饰符不能删)

Python脚本如下(build/zoo.py)

import boost

def show():
boost.show_list([2,3,4]) if __name__ == '__main__':
pass

导出头文件如下(include/boost_wrapper.h)

#pragma once

#include <vector>

void show_list(std::vector<int> const &v);

导出实现如下(src/boost_wrapper.cpp)

#include <iostream>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/to_python_converter.hpp>
#include "boost_wrapper.h" using namespace boost::python;
using namespace boost::python::detail; void show_list(std::vector<int> const &v)
{
for (auto item : v)
{
std::cout << item << " ";
}
std::cout << std::endl;
} template<class ContainerType>
class from_python_list
{
public:
from_python_list()
{
boost::python::converter::registry::push_back(&convertible, &construct, boost::python::type_id<ContainerType>());
} static void* convertible(PyObject *obj_ptr)
{
if (!(PyList_Check(obj_ptr)
|| PyTuple_Check(obj_ptr)
|| PyIter_Check(obj_ptr)
|| PyRange_Check(obj_ptr)
|| (PyObject_HasAttrString(obj_ptr, "__len__") && PyObject_HasAttrString(obj_ptr, "__getitem__"))))
return 0; return obj_ptr;
} static void construct(PyObject *obj_ptr, boost::python::converter::rvalue_from_python_stage1_data* data)
{
boost::python::handle<> obj_iter(PyObject_GetIter(obj_ptr));
void *storage = ((boost::python::converter::rvalue_from_python_storage<ContainerType>*)data)->storage.bytes;
new (storage) ContainerType();
data->convertible = storage;
ContainerType &result = *((ContainerType*)storage); while (true)
{
boost::python::handle<> py_hdl(boost::python::allow_null(PyIter_Next(obj_iter.get())));
if (PyErr_Occurred())
boost::python::throw_error_already_set();
if (!py_hdl.get())
break;
boost::python::object py_obj(py_hdl);
boost::python::extract<typename ContainerType::value_type> obj(py_obj);
result.push_back(obj);
}
}
}; BOOST_PYTHON_MODULE_INIT(boost)
{
def("show_list", show_list);
from_python_list<std::vector<int>>();
}

Boost Python学习笔记(四)的更多相关文章

  1. Boost Python学习笔记(五)

    你将学到什么 在C++中调用Python代码时的返回值问题 基础类型 修改Python脚本(build/zoo.py) def rint(): return 2 def rstr(): return ...

  2. Boost Python学习笔记(二)

    你将学到什么 如何在Python中调用C++代码 如何在C++中调用Python代码 在Python中调用C++代码 首先定义一个动物类(include/animal.h) #pragma once ...

  3. Boost Python学习笔记(三)

    你将学到什么 在C++中调用Python代码时的传参问题 基础类型 继续使用前面的项目,但是先修改下Python脚本(zoo.py),添加Add和Str函数,分别针对整数.浮点数和字符串参数的测试 d ...

  4. Python学习笔记(四)Python函数的参数

    Python的函数除了正常使用的必选参数外,还可以使用默认参数.可变参数和关键字参数. 默认参数 基本使用 默认参数就是可以给特定的参数设置一个默认值,调用函数时,有默认值得参数可以不进行赋值,如: ...

  5. Python学习笔记四

    一.装饰器 1.知识储备 函数对象 函数可以被引用 函数可以当参数传递 返回值可以是函数 可以当作容器的元素 def func1(): print (666) def func2(): print ( ...

  6. Python学习笔记四:面向对象编程

    一:定义类并创建实例 Python中定义类,通过class关键字,类名开头大写,参数列表为所继承的父类.如果没有需要明确继承的类,则继承object. 使用类来创建对象,只需 类名+() 形式即可,p ...

  7. python学习笔记(四) 思考和准备

    一.zip的坑 zip()函数接收多个可迭代数列,将数列中的元素重新组合,在3.0中返回迭代器指向 数列首地址,在3.0以下版本返回List类型的列表数列.我用的是3.5版本python, 所以zip ...

  8. python学习笔记(四):函数

    一.函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序),在Pasc ...

  9. Boost Python学习笔记(一)

    开发环境搭建 下载源码 boost_1_66_0.tar.gz 生成编译工具 # tar axf boost_1_66_0.tar.gz # cd boost_1_66_0 # yum install ...

随机推荐

  1. form表单验证失败,阻止表单提交

    form表单验证失败,阻止表单提交 效果演示: 贴上完整代码: <!DOCTYPE html> <html lang="en"> <head> ...

  2. HTML5学习记录——3

    HTML媒体 1.HTML多媒体 视频格式 .avi    微软开发 .wmv  微软开发 .mpg  .mpeg .mov 苹果公司开发 .rm  .ram  允许低带宽的视频流 .swf  .fl ...

  3. WingIDE用法笔记

    注释代码块 方法一:  ''' 被注释的代码块 '''   方法二:  选中要注释的代码块后 Ctrl + /,则选中的每一行都被# ,   用这种方法注释的代码,用Shift + Ctrl + / ...

  4. Struts2 - 配置文件详解

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "- ...

  5. android 应用程序Activity之间数据传递与共享的几种途径

    一.基于消息的通信机制 Intent ---boudle ,extraAndroid为了屏蔽进程的概念,利用不同的组件[Activity.Service]来表示进程之间的通信!组件间通信的核心机制是I ...

  6. windows 10 安装 spark 环境(spark 2.2.1 + hadoop2.7)

    安装步骤基本参考 Spark在Windows下的环境搭建.不过在安装新版本 spark2.2.1(基于 hadoop2.7)的配置时,略略有一些不同. 1. sqlContext => spar ...

  7. bzoj5329 战略游戏

    有一个圆方树,每次给出一个点集,询问虚树上圆点数量-询问点数量 sol:题意读懂就很简单了...可以建虚树dp 也可以考虑每一条链对答案的贡献,最后要注意单独计算虚树根对答案的贡献 #pragma G ...

  8. luogu1833 樱花

    背包问题小合集 01背包 完全背包 多重背包混着来 对于01背包:把它想象成最大物品数为1的多重背包 对于完全背包:把它想象成最大物品数为m/w[i]的多重背包 对于多重背包:把它想象成...等等这本 ...

  9. diea破解

    选择菜单Help->Register->License server,填上http://idea.iteblog.com/key.php,如图所示:  点击Activate,然后就搞定了.

  10. ACM学习历程—UESTC 1222 Sudoku(矩阵)(2015CCPC H)

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1226 题目大意就是构造一个行列和每个角的2*2都是1234的4*4矩阵. 用dfs暴力搜索,不过需要每一步进 ...