pybind11类型转换实例

2022-04-21  本文已影响0人  JeremyL

#1. C++中的原生态类型,Python中的包装器

#examplePet.cpp

#include <pybind11/pybind11.h>
namespace py = pybind11;

struct Pet {
    Pet(const std::string &name) : name(name) { }
    void setName(const std::string &name_) { name = name_; }
    const std::string &getName() const { return name; }

    std::string name;
};

PYBIND11_MODULE(examplePet, m) {
    py::class_<Pet>(m, "Pet")
        .def(py::init<const std::string &>())//对应c++类构造函数
        .def("setName", &Pet::setName)
        .def("getName", &Pet::getName);
}

# 编译

g++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) examplePet.cpp -o examplePet$(python3-config --extension-suffix)

# 使用

>>> import examplePet
>>> p = examplePet.Pet("Molly")
>>> print(p)
>>> p.getName()
'Molly'
>>> p.setName("Charly")
>>> p.getName()
'Charly'

#2. python中的原生态类型,c++中的包装器

c++想获取python中原生态的数据(tuple或者list),使用py::object

各种接口见:Python types

# printlist.cpp

#include <iostream>
#include <pybind11/pybind11.h>

namespace py = pybind11;

#include <pybind11/stl.h>

void print_list(py::list my_list) {
    for (auto item : my_list)
        std::cout << item << " ";
}

PYBIND11_MODULE( printlist, m ){
    m.doc() = "pybind11 example";
    m.def("print_list", &print_list, "add two number" );
}

Python list没有以任何方式被转换;它只是被封装在C++ PY::list类中。它的核心仍然是一个Python对象。复制py::list将像在Python中进行常规的引用计算。将对象返回到Python只会删除包装器。

g++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) printlist.cpp -o printlist$(python3-config --extension-suffix)
>>> import printvector2
>>> printvector2.print_vector([1, 2, 3])
1 2 3 

#3. 原生态C++与Python类型之间的转换

#printvector.cpp

#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

void print_vector(const std::vector<int> &v) {
    for (auto item : v)
        std::cout << item << "\n";
}

PYBIND11_MODULE( printvector, m ){
    m.doc() = "pybind11 example";
    m.def("print_vector", &print_vector, "add two number" );
}

这与前两种情况不一样;pybind11 创建了一个新的std::vector<int>, 他的元素都是从python list中拷贝而来;std::vector<int>传递给print_vector时,其元素也会拷贝给一个新的python list;对于大数据这是一个耗时耗资源的过程。

g++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) printvector.cpp -o printvector$(python3-config --extension-suffix)
import printvector
printvector.print_vector([1, 2, 3])

更多数据类型转换见:List of all builtin conversions

python的包装数据类型包括 handle, object, bool_, int_, float_, str, bytes, tuple,list, dict, slice, none, capsule, iterable, iterator, function, buffer, array, 和array_t.

# 原文

Type conversion overview

Python types

上一篇 下一篇

猜你喜欢

热点阅读