Boost Python学习笔记(三)

你将学到什么

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

基础类型

继续使用前面的项目,但是先修改下Python脚本(zoo.py),添加AddStr函数,分别针对整数、浮点数和字符串参数的测试

def Add(x, y):
    print(x + y)

def Str(s):
    print("Output: " + s)

if __name__ == '__main__':
    pass

然后修改下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("Add")(object(2), object(4));
    module.attr("Add")(object(3.0f), object(4));
    module.attr("Str")(object("test"));
  }
  catch (const error_already_set&)
  {
    PyErr_Print();
  }
  Py_Finalize();
  return 0;
}

编译并测试

# cd build
# make
# ./core
6
7.0
Output: test

类实例

首先修改下Python脚本(zoo.py),添加Pet函数,针对类实例参数的测试,其参数为Animal类实例

import boost

def Pet(obj):
    obj.eat("meat")
    print(type(obj))
    print(isinstance(obj, boost.Animal))

if __name__ == '__main__':
    pass

然后修改下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");
    object o =  class_<AnimalWrap, boost::noncopyable>("Animal", init<std::string>())
        .def("call", &Animal::call)
        .def("move", &Animal::move)
        .def("eat", &Animal::eat)("Wangcai");
    module.attr("Pet")(o);
  }
  catch (const error_already_set&)
  {
    PyErr_Print();
  }
  Py_Finalize();
  return 0;
}

编译并测试

# cd build
# make
# ./core
Wangcai: eat meat
<class 'Animal'>
False

标准库

首先修改下Python脚本(zoo.py),添加tListtDicttTuple函数,分别用于测试std::vector/std::liststd::map以及数组

def tList(l):
    for i in l:
        print(i)

def tDict(d):
    for k in d:
        print(str(k) + ":" + str(d[k]))

def tTuple(t):
    for i in t:
        print(i)

if __name__ == '__main__':
    pass

然后修改下main.cpp源文件

#include <iostream>
#include <vector>
#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");
    list l;
    l.append(2);
    l.append("dog");
    std::vector<int> v = {3, 4, 5, 6};
    for (auto item : v)
        l.append(item);
    module.attr("tList")(l);
    dict d;
    d.setdefault("fwd", 28);
    d.setdefault("xb", 26);
    module.attr("tDict")(d);
    tuple t = make_tuple("fwd", 28, "xb", 26);
    module.attr("tTuple")(t);
  }
  catch (const error_already_set&)
  {
    PyErr_Print();
  }
  Py_Finalize();
  return 0;
}

编译并测试

# cd build
# make
# ./core
2
dog
3
4
5
6
fwd:28
xb:26
fwd
28
xb
26

总结

类实例还是尽量导出后在Python脚本中创建,如果在C++代码中创建,然后传入Python脚本的话,它的类型并不是boost.Animal,这就导致无法使用isinstance来区分对象。

posted @ 2018-05-25 11:07  银魔术师  阅读(1013)  评论(0编辑  收藏  举报